aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbob <bcz@cs.brown.edu>2019-05-21 12:35:38 -0400
committerbob <bcz@cs.brown.edu>2019-05-21 12:35:38 -0400
commita8717e39df75cbd1fd13435ee9028f230a833399 (patch)
treea17bf828e79e0f20ceb55546915d0bf4be41928e
parent7bafa21e8c37826686a012151674b71631fa9c8b (diff)
parentcfb7fdb1a7b2db263502677e57ee882a6fe23f13 (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-rw-r--r--package.json1
-rw-r--r--src/client/util/type_decls.d33
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx10
-rw-r--r--src/client/views/collections/CollectionSubView.tsx6
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx5
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx2
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx10
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx5
-rw-r--r--src/client/views/nodes/ImageBox.tsx2
-rw-r--r--src/client/views/nodes/KeyValuePair.tsx8
-rw-r--r--src/debug/Viewer.tsx2
-rw-r--r--src/new_fields/CursorField.ts9
-rw-r--r--src/new_fields/Doc.ts8
-rw-r--r--src/new_fields/URLField.ts9
14 files changed, 68 insertions, 42 deletions
diff --git a/package.json b/package.json
index 790535728..aa4abb0a5 100644
--- a/package.json
+++ b/package.json
@@ -126,6 +126,7 @@
"mobx": "^5.9.0",
"mobx-react": "^5.3.5",
"mobx-react-devtools": "^6.1.1",
+ "mobx-utils": "^5.4.0",
"mongodb": "^3.1.13",
"mongoose": "^5.4.18",
"node-sass": "^4.12.0",
diff --git a/src/client/util/type_decls.d b/src/client/util/type_decls.d
index 51114d0e2..557f6f574 100644
--- a/src/client/util/type_decls.d
+++ b/src/client/util/type_decls.d
@@ -140,33 +140,50 @@ declare const ToScriptString: unique symbol;
declare abstract class RefField {
readonly [Id]: FieldId;
- constructor(id?: FieldId);
- protected [HandleUpdate]?(diff: any): void;
+ constructor();
+ // protected [HandleUpdate]?(diff: any): void;
- abstract [ToScriptString](): string;
+ // abstract [ToScriptString](): string;
}
declare abstract class ObjectField {
protected [OnUpdate](diff?: any): void;
private [Parent]?: RefField | ObjectField;
- abstract [Copy](): ObjectField;
+ // abstract [Copy](): ObjectField;
- abstract [ToScriptString](): string;
+ // abstract [ToScriptString](): string;
}
+
+declare abstract class URLField extends ObjectField {
+ readonly url: URL;
+
+ constructor(url: string);
+ constructor(url: URL);
+}
+
+declare class AudioField extends URLField { }
+declare class VideoField extends URLField { }
+declare class ImageField extends URLField { }
+declare class WebField extends URLField { }
+declare class PdfField extends URLField { }
+
declare type FieldId = string;
declare type Field = number | string | boolean | ObjectField | RefField;
declare type Opt<T> = T | undefined;
declare class Doc extends RefField {
+ constructor();
+
[key: string]: Field | undefined;
- [ToScriptString](): string;
+ // [ToScriptString](): string;
}
declare class ListImpl<T extends Field> extends ObjectField {
+ constructor(fields?: T[]);
[index: number]: T | (T extends RefField ? Promise<T> : never);
- [ToScriptString](): string;
- [Copy](): ObjectField;
+ // [ToScriptString](): string;
+ // [Copy](): ObjectField;
}
// @ts-ignore
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index c42a0332d..bfd70ceae 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -124,22 +124,20 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
height={Number(MAX_ROW_HEIGHT)}
GetValue={() => {
let field = props.Document[props.fieldKey];
- if (field) {
- //TODO Types
- // return field.ToScriptString();
- return String(field);
+ if (Field.IsField(field)) {
+ return Field.toScriptString(field);
}
return "";
}}
SetValue={(value: string) => {
- let script = CompileScript(value, { addReturn: true, params: { this: Document.name } });
+ let script = CompileScript(value, { addReturn: true, params: { this: Doc.name } });
if (!script.compiled) {
return false;
}
return applyToDoc(props.Document, script.run);
}}
OnFillDown={async (value: string) => {
- let script = CompileScript(value, { addReturn: true, params: { this: Document.name } });
+ let script = CompileScript(value, { addReturn: true, params: { this: Doc.name } });
if (!script.compiled) {
return;
}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 864fdfa4b..7800b35df 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -16,9 +16,7 @@ import { listSpec } from "../../../new_fields/Schema";
import { Cast, PromiseValue, FieldValue, ListSpec } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
import { DocServer } from "../../DocServer";
-import { ObjectField } from "../../../new_fields/ObjectField";
-import CursorField, { CursorPosition, CursorMetadata } from "../../../new_fields/CursorField";
-import { url } from "inspector";
+import CursorField from "../../../new_fields/CursorField";
export interface CollectionViewProps extends FieldViewProps {
addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
@@ -72,7 +70,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
if (cursors.length > 0 && (ind = cursors.findIndex(entry => entry.data.metadata.id === id)) > -1) {
cursors[ind].setPosition(pos);
} else {
- let entry = new CursorField({ metadata: { id: id, identifier: email }, position: pos });
+ let entry = new CursorField({ metadata: { id: id, identifier: email, timestamp: Date.now() }, position: pos });
cursors.push(entry);
}
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
index 642118d75..2838b7905 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
@@ -9,6 +9,7 @@ import CursorField from "../../../../new_fields/CursorField";
import { List } from "../../../../new_fields/List";
import { Cast } from "../../../../new_fields/Types";
import { listSpec } from "../../../../new_fields/Schema";
+import * as mobxUtils from 'mobx-utils';
@observer
export class CollectionFreeFormRemoteCursors extends React.Component<CollectionViewProps> {
@@ -23,7 +24,9 @@ export class CollectionFreeFormRemoteCursors extends React.Component<CollectionV
let cursors = Cast(doc.cursors, listSpec(CursorField));
- return (cursors || []).filter(cursor => cursor.data.metadata.id !== id);
+ const now = mobxUtils.now();
+ // const now = Date.now();
+ return (cursors || []).filter(cursor => cursor.data.metadata.id !== id && (now - cursor.data.metadata.timestamp) < 1000);
}
private crosshairs?: HTMLCanvasElement;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ba6a4bbab..7a0a02318 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -183,7 +183,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
return;
}
e.stopPropagation();
- const coefficient = 100;
+ const coefficient = 1000;
if (e.ctrlKey) {
let deltaScale = (1 - (e.deltaY / coefficient));
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index bf0c272e3..aaaa6a9c5 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -266,15 +266,15 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
let maximizedDoc = FieldValue(Cast(this.props.Document.maximizedDocs, listSpec(Doc)));
let zoomFade = 1;
//var zoom = doc.GetNumber(KeyStore.ZoomBasis, 1);
- let transform = this.getTransform().scale(this.contentScaling()).inverse();
- var [sptX, sptY] = transform.transformPoint(0, 0);
- let [bptX, bptY] = transform.transformPoint(this.props.PanelWidth(), this.props.PanelHeight());
- let w = bptX - sptX;
+ // let transform = this.getTransform().scale(this.contentScaling()).inverse();
+ // var [sptX, sptY] = transform.transformPoint(0, 0);
+ // let [bptX, bptY] = transform.transformPoint(this.props.PanelWidth(), this.props.PanelHeight());
+ // let w = bptX - sptX;
//zoomFade = area < 100 || area > 800 ? Math.max(0, Math.min(1, 2 - 5 * (zoom < this.scale ? this.scale / zoom : zoom / this.scale))) : 1;
const screenWidth = Math.min(50 * NumCast(this.props.Document.nativeWidth, 0), 1800);
let fadeUp = .75 * screenWidth;
let fadeDown = (maximizedDoc ? .0075 : .075) * screenWidth;
- zoomFade = w < fadeDown /* || w > fadeUp */ ? Math.max(0.1, Math.min(1, 2 - (w < fadeDown ? Math.sqrt(Math.sqrt(fadeDown / w)) : w / fadeUp))) : 1;
+ // zoomFade = w < fadeDown /* || w > fadeUp */ ? Math.max(0.1, Math.min(1, 2 - (w < fadeDown ? Math.sqrt(Math.sqrt(fadeDown / w)) : w / fadeUp))) : 1;
return (
<div className="collectionFreeFormDocumentView-container" ref={this._mainCont}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index d2cb11586..52a9582d2 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -90,8 +90,9 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
Math.min(NumCast(self.props.Document.width, 0),
px * self.props.ScreenToLocalTransform().Scale))}px`;
}
- let nativizedTemplate = template.replace(/([0-9]+)px/g, convertConstantsToNative);
- layout = nativizedTemplate.replace("{layout}", base);
+ // let nativizedTemplate = template.replace(/([0-9]+)px/g, convertConstantsToNative);
+ // layout = nativizedTemplate.replace("{layout}", base);
+ layout = template.replace("{layout}", base);
base = layout;
});
}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index e022793eb..d9d964ee9 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -1,4 +1,4 @@
-import { action, observable } from 'mobx';
+import { action, observable, trace } from 'mobx';
import { observer } from "mobx-react";
import Lightbox from 'react-image-lightbox';
import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 7a88985c0..2363553df 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -60,10 +60,8 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
<EditableView contents={contents} height={36} GetValue={() => {
let field = FieldValue(props.Document[props.fieldKey]);
- if (field) {
- //TODO Types
- return String(field);
- // return field.ToScriptString();
+ if (Field.IsField(field)) {
+ return Field.toScriptString(field);
}
return "";
}}
@@ -75,7 +73,7 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
let res = script.run();
if (!res.success) return false;
const field = res.result;
- if (Field.IsField(field)) {
+ if (Field.IsField(field, true)) {
props.Document[props.fieldKey] = field;
return true;
}
diff --git a/src/debug/Viewer.tsx b/src/debug/Viewer.tsx
index 4314e2132..b22300d0b 100644
--- a/src/debug/Viewer.tsx
+++ b/src/debug/Viewer.tsx
@@ -20,7 +20,7 @@ function applyToDoc(doc: any, key: string | number, scriptString: string): boole
}
const res = script.run({ this: doc });
if (!res.success) return false;
- if (!Field.IsField(res.result)) return false;
+ if (!Field.IsField(res.result, true)) return false;
doc[key] = res.result;
return true;
}
diff --git a/src/new_fields/CursorField.ts b/src/new_fields/CursorField.ts
index 1be1ec3e0..fd86031a8 100644
--- a/src/new_fields/CursorField.ts
+++ b/src/new_fields/CursorField.ts
@@ -1,7 +1,7 @@
import { ObjectField } from "./ObjectField";
import { observable } from "mobx";
import { Deserializable } from "../client/util/SerializationHelper";
-import { serializable, createSimpleSchema, object } from "serializr";
+import { serializable, createSimpleSchema, object, date } from "serializr";
import { OnUpdate, ToScriptString, Copy } from "./FieldSymbols";
export type CursorPosition = {
@@ -11,7 +11,8 @@ export type CursorPosition = {
export type CursorMetadata = {
id: string,
- identifier: string
+ identifier: string,
+ timestamp: number
};
export type CursorData = {
@@ -26,7 +27,8 @@ const PositionSchema = createSimpleSchema({
const MetadataSchema = createSimpleSchema({
id: true,
- identifier: true
+ identifier: true,
+ timestamp: true
});
const CursorSchema = createSimpleSchema({
@@ -47,6 +49,7 @@ export default class CursorField extends ObjectField {
setPosition(position: CursorPosition) {
this.data.position = position;
+ this.data.metadata.timestamp = Date.now();
this[OnUpdate]();
}
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 92d3c140a..b0237d04d 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -19,12 +19,15 @@ export namespace Field {
return field[ToScriptString]();
}
}
- export function IsField(field: any): field is Field {
+ export function IsField(field: any): field is Field;
+ export function IsField(field: any, includeUndefined: true): field is Field | undefined;
+ export function IsField(field: any, includeUndefined: boolean = false): field is Field | undefined {
return (typeof field === "string")
|| (typeof field === "number")
|| (typeof field === "boolean")
|| (field instanceof ObjectField)
- || (field instanceof RefField);
+ || (field instanceof RefField)
+ || (includeUndefined && field === undefined);
}
}
export type Field = number | string | boolean | ObjectField | RefField;
@@ -116,7 +119,6 @@ export class Doc extends RefField {
}
public [HandleUpdate](diff: any) {
- console.log(diff);
const set = diff.$set;
if (set) {
for (const key in set) {
diff --git a/src/new_fields/URLField.ts b/src/new_fields/URLField.ts
index a6f8f1cc5..4a2841fb6 100644
--- a/src/new_fields/URLField.ts
+++ b/src/new_fields/URLField.ts
@@ -18,13 +18,18 @@ export abstract class URLField extends ObjectField {
@serializable(url())
readonly url: URL;
- constructor(url: URL) {
+ constructor(url: string);
+ constructor(url: URL);
+ constructor(url: URL | string) {
super();
+ if (typeof url === "string") {
+ url = new URL(url);
+ }
this.url = url;
}
[ToScriptString]() {
- return `new ${this.constructor.name}(new URL(${this.url.href}))`;
+ return `new ${this.constructor.name}("${this.url.href}")`;
}
[Copy](): this {