aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/PreviewTextCursor.tsx15
-rw-r--r--src/client/util/SelectionManager.ts1
-rw-r--r--src/client/views/collections/CollectionFreeFormView.scss18
-rw-r--r--src/client/views/collections/CollectionFreeFormView.tsx66
-rw-r--r--src/client/views/collections/CollectionView.tsx7
-rw-r--r--src/client/views/nodes/DocumentView.tsx3
-rw-r--r--src/client/views/nodes/FormattedTextBox.scss2
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx34
-rw-r--r--src/fields/Key.ts1
-rw-r--r--src/fields/KeyStore.ts6
-rw-r--r--src/server/database.ts11
11 files changed, 152 insertions, 12 deletions
diff --git a/src/PreviewTextCursor.tsx b/src/PreviewTextCursor.tsx
new file mode 100644
index 000000000..6818bf28c
--- /dev/null
+++ b/src/PreviewTextCursor.tsx
@@ -0,0 +1,15 @@
+import React = require("react");
+import { observer } from "mobx-react";
+
+@observer
+export class PreviewTextCursor extends React.Component {
+
+ render() {
+ return (
+ <div>
+
+ </div>
+ )
+ };
+
+} \ No newline at end of file
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 1a711ae64..c349e7631 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -8,6 +8,7 @@ export namespace SelectionManager {
@action
SelectDoc(doc: DocumentView, ctrlPressed: boolean): void {
+
// if doc is not in SelectedDocuments, add it
if (!ctrlPressed) {
manager.SelectedDocuments = [];
diff --git a/src/client/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss
index 737f28318..f7b2e6449 100644
--- a/src/client/views/collections/CollectionFreeFormView.scss
+++ b/src/client/views/collections/CollectionFreeFormView.scss
@@ -30,4 +30,22 @@
width:100%;
height: 100%
}
+}
+
+.border {
+ border-style: solid;
+ box-sizing: border-box;
+ width: 100%;
+ height: 100%;
+}
+
+//this is an animation for the blinking cursor!
+@keyframes blink {
+ 0% {opacity: 0}
+ 49%{opacity: 0}
+ 50% {opacity: 1}
+}
+
+#prevCursor {
+ animation: blink 1s infinite;
} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 12909c151..cd88c931b 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -1,7 +1,9 @@
-import { action, computed } from "mobx";
+import { observable, action, computed } from "mobx";
import { observer } from "mobx-react";
import { Document } from "../../../fields/Document";
import { FieldWaiting } from "../../../fields/Field";
+import { Server } from "tls";
+import { RichTextField } from "../../../fields/RichTextField";
import { KeyStore } from "../../../fields/KeyStore";
import { ListField } from "../../../fields/ListField";
import { TextField } from "../../../fields/TextField";
@@ -20,6 +22,7 @@ import { ImageBox } from "../nodes/ImageBox";
import "./CollectionFreeFormView.scss";
import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
import { CollectionViewBase } from "./CollectionViewBase";
+import { Documents } from "../../documents/Documents";
import React = require("react");
const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this?
@@ -28,9 +31,18 @@ export class CollectionFreeFormView extends CollectionViewBase {
private _canvasRef = React.createRef<HTMLDivElement>();
private _lastX: number = 0;
private _lastY: number = 0;
+
+ @observable
private _downX: number = 0;
+ @observable
private _downY: number = 0;
+ //determines whether the blinking cursor for indicating whether a text will be made on key down is visible
+ @observable
+ private _previewCursorVisible: boolean = false;
+
+ @computed get colFocus(): boolean { return this.props.CollectionView.isFocusOn() }
+
@computed get panX(): number { return this.props.Document.GetNumber(KeyStore.PanX, 0) }
@computed get panY(): number { return this.props.Document.GetNumber(KeyStore.PanY, 0) }
@computed get scale(): number { return this.props.Document.GetNumber(KeyStore.Scale, 1); }
@@ -63,8 +75,10 @@ export class CollectionFreeFormView extends CollectionViewBase {
document.addEventListener("pointermove", this.onPointerMove);
document.removeEventListener("pointerup", this.onPointerUp);
document.addEventListener("pointerup", this.onPointerUp);
- this._downX = this._lastX = e.pageX;
- this._downY = this._lastY = e.pageY;
+ this._lastX = e.pageX;
+ this._lastY = e.pageY;
+ this._downX = e.pageX;
+ this._downY = e.pageY;
}
}
@@ -74,10 +88,14 @@ export class CollectionFreeFormView extends CollectionViewBase {
document.removeEventListener("pointerup", this.onPointerUp);
e.stopPropagation();
if (Math.abs(this._downX - e.clientX) < 3 && Math.abs(this._downY - e.clientY) < 3) {
+ //show preview text cursor on tap
+ this._previewCursorVisible = true;
+ //select is not already selected
if (!this.props.isSelected()) {
this.props.select(false);
}
}
+
}
@action
@@ -88,7 +106,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
let x = this.props.Document.GetNumber(KeyStore.PanX, 0);
let y = this.props.Document.GetNumber(KeyStore.PanY, 0);
let [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
-
+ this._previewCursorVisible = false;
this.SetPan(x + dx, y + dy);
}
this._lastX = e.pageX;
@@ -146,6 +164,26 @@ export class CollectionFreeFormView extends CollectionViewBase {
}
@action
+ onKeyDown = (e: React.KeyboardEvent<Element>) => {
+ console.log("KEY PRESSED");
+ //if not these keys, make a textbox if preview cursor is active!
+ if (!e.ctrlKey && !e.altKey && !e.shiftKey) {
+ if (this._previewCursorVisible) {
+ //make textbox and add it to this collection
+ let [x, y] = this.getTransform().transformPoint(this._downX, this._downY); (this._downX, this._downY);
+ let newBox = Documents.TextDocument({ width: 200, height: 100, x: x, y: y, title: "new" });
+ //set text to be the typed key and get focus on text box
+ this.props.CollectionView.addDocument(newBox);
+ newBox.SetText(KeyStore.Data, e.key);
+ newBox.SetNumber(KeyStore.SelectOnLoaded, 1);
+
+ //remove cursor from screen
+ this._previewCursorVisible = false;
+ }
+ }
+ }
+
+ @action
bringToFront(doc: Document) {
const { fieldKey: fieldKey, Document: Document } = this.props;
@@ -223,22 +261,42 @@ export class CollectionFreeFormView extends CollectionViewBase {
getLocalTransform = (): Transform => Transform.Identity.translate(-this.panX, -this.panY).scale(1 / this.scale);
noScaling = () => 1;
+ //when focus is lost, this will remove the preview cursor
+ @action
+ onBlur = (e: React.FocusEvent<HTMLInputElement>): void => {
+ this._previewCursorVisible = false;
+ }
+
render() {
+
+ //determines whether preview text cursor should be visible (ie when user taps this collection it should)
+ let cursor = null;
+ if (this._previewCursorVisible) {
+ //get local position and place cursor there!
+ let [x, y] = this.getTransform().transformPoint(this._downX, this._downY);
+ cursor = <div id="prevCursor" onKeyPress={this.onKeyDown} style={{ color: "black", position: "absolute", transformOrigin: "left top", transform: `translate(${x}px, ${y}px)` }}>I</div>
+ }
+
const panx: number = this.props.Document.GetNumber(KeyStore.PanX, 0) + this.centeringShiftX;
const pany: number = this.props.Document.GetNumber(KeyStore.PanY, 0) + this.centeringShiftY;
+
return (
<div className="collectionfreeformview-container"
onPointerDown={this.onPointerDown}
+ onKeyPress={this.onKeyDown}
onWheel={this.onPointerWheel}
onContextMenu={(e) => e.preventDefault()}
onDrop={this.onDrop.bind(this)}
onDragOver={this.onDragOver}
+ onBlur={this.onBlur}
style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px`, }}
+ tabIndex={0}
ref={this.createDropTarget}>
<div className="collectionfreeformview"
style={{ transformOrigin: "left top", transform: ` translate(${panx}px, ${pany}px) scale(${this.zoomScaling}, ${this.zoomScaling})` }}
ref={this._canvasRef}>
{this.backgroundView}
+ {cursor}
{this.views}
</div>
{this.overlayView}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 03e1f1fa4..11cc6d28e 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -1,4 +1,4 @@
-import { action, computed } from "mobx";
+import { action, computed, observable } from "mobx";
import { observer } from "mobx-react";
import { Document } from "../../../fields/Document";
import { ListField } from "../../../fields/ListField";
@@ -11,6 +11,7 @@ import { CollectionFreeFormView } from "./CollectionFreeFormView";
import { CollectionDockingView } from "./CollectionDockingView";
import { CollectionSchemaView } from "./CollectionSchemaView";
import { CollectionViewProps } from "./CollectionViewBase";
+var ReactDOM = require('react-dom');
import { CollectionTreeView } from "./CollectionTreeView";
import { Field } from "../../../fields/Field";
@@ -87,13 +88,15 @@ export class CollectionView extends React.Component<CollectionViewProps> {
Document.SetData(KeyStore.ViewType, type, NumberField);
}
+
render() {
let viewType = this.collectionViewType;
+
switch (viewType) {
case CollectionViewType.Freeform:
return (<CollectionFreeFormView {...this.props}
addDocument={this.addDocument} removeDocument={this.removeDocument} active={this.active}
- CollectionView={this} />)
+ CollectionView={this} />);
case CollectionViewType.Schema:
return (<CollectionSchemaView {...this.props}
addDocument={this.addDocument} removeDocument={this.removeDocument} active={this.active}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index c579b7142..9f80c4e3a 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -113,12 +113,14 @@ export class DocumentView extends React.Component<DocumentViewProps> {
}
}
+
onPointerMove = (e: PointerEvent): void => {
if (e.cancelBubble) {
this._contextMenuCanOpen = false;
return;
}
if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) {
+
this._contextMenuCanOpen = false;
if (this._mainCont.current != null && !this.topMost) {
this._contextMenuCanOpen = false;
@@ -202,6 +204,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
onError={(test: any) => { console.log(test) }}
/>
}
+
render() {
if (!this.props.Document)
return <div></div>
diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss
index f06fdae24..21bd43b6e 100644
--- a/src/client/views/nodes/FormattedTextBox.scss
+++ b/src/client/views/nodes/FormattedTextBox.scss
@@ -9,7 +9,7 @@
}
.formattedTextBox-cont {
- background: rgb(218, 215, 215);
+ background: white;
padding: 1;
border: black;
border-width: 10;
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index a58e1955f..63d00a310 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -3,13 +3,21 @@ import { baseKeymap } from "prosemirror-commands";
import { history, redo, undo } from "prosemirror-history";
import { keymap } from "prosemirror-keymap";
import { schema } from "prosemirror-schema-basic";
+import { Transform } from "prosemirror-transform";
import { EditorState, Transaction } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
+import { Node } from "prosemirror-model";
import { Opt, FieldWaiting, FieldValue } from "../../../fields/Field";
import "./FormattedTextBox.scss";
+import { KeyStore } from "../../../fields/KeyStore";
import React = require("react")
import { RichTextField } from "../../../fields/RichTextField";
import { FieldViewProps, FieldView } from "./FieldView";
+import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
+import { observer } from "mobx-react";
+import { Schema, DOMParser } from "prosemirror-model"
+import { Plugin } from 'prosemirror-state'
+import { Decoration, DecorationSet } from 'prosemirror-view'
// FormattedTextBox: Displays an editable plain text node that maps to a specified Key of a Document
@@ -34,6 +42,7 @@ export class FormattedTextBox extends React.Component<FieldViewProps> {
private _ref: React.RefObject<HTMLDivElement>;
private _editorView: Opt<EditorView>;
private _reactionDisposer: Opt<IReactionDisposer>;
+ private _lastTextState = "";
constructor(props: FieldViewProps) {
super(props);
@@ -49,9 +58,24 @@ export class FormattedTextBox extends React.Component<FieldViewProps> {
this._editorView.updateState(state);
const { doc, fieldKey } = this.props;
doc.SetData(fieldKey, JSON.stringify(state.toJSON()), RichTextField);
+ this._lastTextState = JSON.stringify(state.toJSON);
}
}
+ //enables textboxes to be created with preexisting text or placeholder text
+ //this method is passed in as part of the config the editor state in componentDidMount()
+ placeholderPlugin(text: string) {
+ return new Plugin({
+ props: {
+ decorations(state) {
+ let doc = state.doc
+ if (doc.childCount == 1 && doc.firstChild && doc.firstChild.isTextblock && doc.firstChild.content.size == 0)
+ return DecorationSet.create(doc, [Decoration.widget(1, document.createTextNode(text))])
+ }
+ }
+ })
+ }
+
componentDidMount() {
let state: EditorState;
const { doc, fieldKey } = this.props;
@@ -60,7 +84,8 @@ export class FormattedTextBox extends React.Component<FieldViewProps> {
plugins: [
history(),
keymap({ "Mod-z": undo, "Mod-y": redo }),
- keymap(baseKeymap)
+ keymap(baseKeymap),
+ //sets the placeholder text to what's in KeyStore.Text!
]
};
@@ -85,6 +110,12 @@ export class FormattedTextBox extends React.Component<FieldViewProps> {
this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field)));
}
})
+
+ //if tagged to be selected when created, then select & focus
+ if (this.props.doc.GetNumber(KeyStore.SelectOnLoaded, 0)) {
+ this.props.select();
+ this._editorView!.focus();
+ }
}
componentWillUnmount() {
@@ -103,6 +134,7 @@ export class FormattedTextBox extends React.Component<FieldViewProps> {
@action
onChange(e: React.ChangeEvent<HTMLInputElement>) {
const { fieldKey, doc } = this.props;
+ this._lastTextState = e.target.value;
doc.SetData(fieldKey, e.target.value, RichTextField);
}
onPointerDown = (e: React.PointerEvent): void => {
diff --git a/src/fields/Key.ts b/src/fields/Key.ts
index c16a00878..00d78d516 100644
--- a/src/fields/Key.ts
+++ b/src/fields/Key.ts
@@ -2,7 +2,6 @@ import { Field, FieldId } from "./Field"
import { Utils } from "../Utils";
import { observable } from "mobx";
import { Types } from "../server/Message";
-import { ObjectID } from "bson";
import { Server } from "../client/Server";
export class Key extends Field {
diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts
index a3b39735d..6b5fafe05 100644
--- a/src/fields/KeyStore.ts
+++ b/src/fields/KeyStore.ts
@@ -26,4 +26,10 @@ export namespace KeyStore {
export const Caption = new Key("Caption");
export const ActiveFrame = new Key("ActiveFrame");
export const DocumentText = new Key("DocumentText");
+ //used for setting the text of a text document
+ export const Text = new Key("Text");
+ //determines whether doc views will be selected when they are first loaded
+ //should be NumberField where 0 = false and 1 = true
+ //currently only implemented for FormattedTextView
+ export const SelectOnLoaded = new Key("SelectOnLoaded");
}
diff --git a/src/server/database.ts b/src/server/database.ts
index 07c5819ab..dbf335c0a 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -1,6 +1,6 @@
import { action, configure } from 'mobx';
-import * as mongodb from 'mongodb';
-import { ObjectID } from 'mongodb';
+import * as mongodb from "mongodb"
+import { ObjectID } from "mongodb"
import { Transferable } from './Message';
import { Utils } from '../Utils';
@@ -8,10 +8,15 @@ export class Database {
public static Instance = new Database()
private MongoClient = mongodb.MongoClient;
private url = 'mongodb://localhost:27017/Dash';
+
private db?: mongodb.Db;
constructor() {
this.MongoClient.connect(this.url, (err, client) => {
+ if (err) {
+ console.log(err.message);
+ throw err;
+ }
this.db = client.db()
})
}
@@ -78,4 +83,4 @@ export class Database {
public print() {
console.log("db says hi!")
}
-}
+} \ No newline at end of file