aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTyler Schicke <tyler_schicke@brown.edu>2019-04-21 23:40:48 -0400
committerTyler Schicke <tyler_schicke@brown.edu>2019-04-21 23:40:48 -0400
commit393d351420b3a0d28f4cd1ea8b674fa5d04bfcde (patch)
tree27f663e4e034949d742294259e021e9826fb0631 /src
parentfd5c4f18d0af6571508f142ca400e6d752f19800 (diff)
More fixes
Diffstat (limited to 'src')
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx6
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx2
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/FieldView.tsx8
-rw-r--r--src/client/views/nodes/ImageBox.tsx15
-rw-r--r--src/client/views/nodes/VideoBox.tsx35
-rw-r--r--src/client/views/nodes/WebBox.tsx4
-rw-r--r--src/debug/Test.tsx12
-rw-r--r--src/new_fields/Doc.ts4
-rw-r--r--src/new_fields/Schema.ts22
-rw-r--r--src/new_fields/Types.ts11
-rw-r--r--src/new_fields/URLField.ts9
12 files changed, 62 insertions, 68 deletions
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 7b204cbdc..86ee7cea9 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -16,7 +16,7 @@ import { ServerUtils } from "../../../server/ServerUtil";
import { DragManager, DragLinksAsDocuments } from "../../util/DragManager";
import { Transform } from '../../util/Transform';
import { Doc, Id, Opt, Field, FieldId } from "../../../new_fields/Doc";
-import { Cast, FieldValue } from "../../../new_fields/Types";
+import { Cast } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
import { DocServer } from "../../DocServer";
@@ -336,8 +336,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
ScreenToLocalTransform = () => {
if (this._mainCont.current && this._mainCont.current.children) {
- let { scale, translateX, translateY } = Utils.GetScreenTransform(this._mainCont.current!.children[0].firstChild as HTMLElement);
- scale = Utils.GetScreenTransform(this._mainCont.current!).scale;
+ let { scale, translateX, translateY } = Utils.GetScreenTransform(this._mainCont.current.children[0].firstChild as HTMLElement);
+ scale = Utils.GetScreenTransform(this._mainCont.current).scale;
return CollectionDockingView.Instance.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(scale / this.contentScaling());
}
return Transform.Identity();
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 27fd25b5c..c6eea5623 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -18,7 +18,7 @@ const schema = createSchema({
});
type FreeformDocument = makeInterface<[typeof schema, typeof positionSchema]>;
-const FreeformDocument = makeInterface([schema, positionSchema]);
+const FreeformDocument = makeInterface(schema, positionSchema);
@observer
export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeFormDocumentViewProps, FreeformDocument>(FreeformDocument) {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index f1a12e6db..c0afc192e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -56,7 +56,7 @@ export const positionSchema = createSchema({
});
type Document = makeInterface<[typeof schema]>;
-const Document = makeInterface([schema]);
+const Document = makeInterface(schema);
@observer
export class DocumentView extends DocComponent<DocumentViewProps, Document>(Document) {
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 845213366..b11a87d75 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -3,19 +3,19 @@ import { observer } from "mobx-react";
import { computed } from "mobx";
import { FormattedTextBox } from "./FormattedTextBox";
import { ImageBox } from "./ImageBox";
-import { WebBox } from "./WebBox";
import { VideoBox } from "./VideoBox";
import { AudioBox } from "./AudioBox";
import { DocumentContentsView } from "./DocumentContentsView";
import { Transform } from "../../util/Transform";
-import { returnFalse, emptyFunction, returnOne } from "../../../Utils";
+import { returnFalse, emptyFunction } from "../../../Utils";
import { CollectionView } from "../collections/CollectionView";
import { CollectionPDFView } from "../collections/CollectionPDFView";
import { CollectionVideoView } from "../collections/CollectionVideoView";
import { IconField } from "../../../fields/IconFIeld";
import { IconBox } from "./IconBox";
-import { Opt, Doc, Field, FieldValue, FieldWaiting } from "../../../new_fields/Doc";
+import { Opt, Doc, FieldResult } from "../../../new_fields/Doc";
import { List } from "../../../new_fields/List";
+import { ImageField, VideoField, AudioField } from "../../../new_fields/URLField";
//
@@ -47,7 +47,7 @@ export class FieldView extends React.Component<FieldViewProps> {
}
@computed
- get field(): FieldValue {
+ get field(): FieldResult {
const { Document, fieldKey } = this.props;
return Document[fieldKey];
}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 3b72e9f39..c11aee56e 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -14,16 +14,15 @@ import { createSchema, makeInterface } from '../../../new_fields/Schema';
import { DocComponent } from '../DocComponent';
import { positionSchema } from './DocumentView';
import { FieldValue, Cast } from '../../../new_fields/Types';
-import { URLField } from '../../../new_fields/URLField';
-import { Doc, FieldWaiting } from '../../../new_fields/Doc';
+import { ImageField } from '../../../new_fields/URLField';
import { List } from '../../../new_fields/List';
-const schema = createSchema({
+export const pageSchema = createSchema({
curPage: "number"
});
-type ImageDocument = makeInterface<[typeof schema, typeof positionSchema]>;
-const ImageDocument = makeInterface([schema, positionSchema]);
+type ImageDocument = makeInterface<[typeof pageSchema, typeof positionSchema]>;
+const ImageDocument = makeInterface(pageSchema, positionSchema);
@observer
export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageDocument) {
@@ -135,7 +134,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
}
specificContextMenu = (e: React.MouseEvent): void => {
- let field = Cast(this.Document[this.props.fieldKey], URLField);
+ let field = Cast(this.Document[this.props.fieldKey], ImageField);
if (field && field !== FieldWaiting) {
let url = field.url.href;
ContextMenu.Instance.addItem({
@@ -167,8 +166,8 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
let field = this.Document[this.props.fieldKey];
let paths: string[] = ["http://www.cs.brown.edu/~bcz/face.gif"];
if (field === FieldWaiting) paths = ["https://image.flaticon.com/icons/svg/66/66163.svg"];
- else if (field instanceof URLField) paths = [field.url.href];
- else if (field instanceof List) paths = field.filter(val => val instanceof URLField).map(p => (p as URLField).url.href);
+ else if (field instanceof ImageField) paths = [field.url.href];
+ else if (field instanceof List) paths = field.filter(val => val instanceof ImageField).map(p => (p as ImageField).url.href);
let nativeWidth = FieldValue(this.Document.nativeWidth, 1);
return (
<div className="imageBox-cont" onPointerDown={this.onPointerDown} onDrop={this.onDrop} ref={this.createDropTarget} onContextMenu={this.specificContextMenu}>
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 9d7c2bc56..7b922b620 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -1,18 +1,22 @@
import React = require("react");
import { observer } from "mobx-react";
-import { FieldWaiting, Opt } from '../../../fields/Field';
-import { VideoField } from '../../../fields/VideoField';
import { FieldView, FieldViewProps } from './FieldView';
import "./VideoBox.scss";
import Measure from "react-measure";
-import { action, trace, observable, IReactionDisposer, computed, reaction } from "mobx";
-import { KeyStore } from "../../../fields/KeyStore";
-import { number } from "prop-types";
+import { action, computed } from "mobx";
+import { DocComponent } from "../DocComponent";
+import { positionSchema } from "./DocumentView";
+import { makeInterface } from "../../../new_fields/Schema";
+import { pageSchema } from "./ImageBox";
+import { Cast, FieldValue } from "../../../new_fields/Types";
+import { VideoField } from "../../../new_fields/URLField";
+
+type VideoDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>;
+const VideoDocument = makeInterface(positionSchema, pageSchema);
@observer
-export class VideoBox extends React.Component<FieldViewProps> {
+export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoDocument) {
- private _reactionDisposer: Opt<IReactionDisposer>;
private _videoRef = React.createRef<HTMLVideoElement>();
public static LayoutString() { return FieldView.LayoutString(VideoBox); }
@@ -20,7 +24,7 @@ export class VideoBox extends React.Component<FieldViewProps> {
super(props);
}
- @computed private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, -1); }
+ @computed private get curPage() { return FieldValue(this.Document.curPage, -1); }
_loaded: boolean = false;
@@ -31,12 +35,12 @@ export class VideoBox extends React.Component<FieldViewProps> {
// bcz: the nativeHeight should really be set when the document is imported.
// also, the native dimensions could be different for different pages of the PDF
// so this design is flawed.
- var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0);
- var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0);
+ var nativeWidth = FieldValue(this.Document.nativeWidth, 0);
+ var nativeHeight = FieldValue(this.Document.nativeHeight, 0);
var newNativeHeight = nativeWidth * r.entry.height / r.entry.width;
if (!nativeHeight && newNativeHeight !== nativeHeight && !isNaN(newNativeHeight)) {
- this.props.Document.SetNumber(KeyStore.Height, newNativeHeight / nativeWidth * this.props.Document.GetNumber(KeyStore.Width, 0));
- this.props.Document.SetNumber(KeyStore.NativeHeight, newNativeHeight);
+ this.Document.height = newNativeHeight / nativeWidth * FieldValue(this.Document.width, 0);
+ this.Document.nativeHeight = newNativeHeight;
}
} else {
this._loaded = true;
@@ -56,12 +60,11 @@ export class VideoBox extends React.Component<FieldViewProps> {
}
render() {
- let field = this.props.Document.GetT(this.props.fieldKey, VideoField);
- if (!field || field === FieldWaiting) {
+ let field = FieldValue(Cast(this.Document[this.props.fieldKey], VideoField));
+ if (!field) {
return <div>Loading</div>;
}
- let path = field.Data.href;
- trace();
+ let path = field.url.href;
return (
<Measure onResize={this.setScaling}>
{({ measureRef }) =>
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index e3b6e1c05..63778fa50 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -4,7 +4,7 @@ import { FieldViewProps, FieldView } from './FieldView';
import { observer } from "mobx-react";
import { computed } from 'mobx';
import { HtmlField } from "../../../new_fields/HtmlField";
-import { URLField } from "../../../new_fields/URLField";
+import { WebField } from "../../../new_fields/URLField";
@observer
export class WebBox extends React.Component<FieldViewProps> {
@@ -37,7 +37,7 @@ export class WebBox extends React.Component<FieldViewProps> {
let view;
if (field instanceof HtmlField) {
view = <span id="webBox-htmlSpan" dangerouslySetInnerHTML={{ __html: field.html }} />
- } else if (field instanceof URLField) {
+ } else if (field instanceof WebField) {
view = <iframe src={field.url.href} style={{ position: "absolute", width: "100%", height: "100%" }} />
} else {
view = <iframe src={"https://crossorigin.me/https://cs.brown.edu"} style={{ position: "absolute", width: "100%", height: "100%" }} />
diff --git a/src/debug/Test.tsx b/src/debug/Test.tsx
index 81c69ca8e..22a39f31e 100644
--- a/src/debug/Test.tsx
+++ b/src/debug/Test.tsx
@@ -2,7 +2,7 @@ import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { SerializationHelper } from '../client/util/SerializationHelper';
import { createSchema, makeInterface, makeStrictInterface } from '../new_fields/Schema';
-import { URLField } from '../new_fields/URLField';
+import { ImageField } from '../new_fields/URLField';
import { Doc } from '../new_fields/Doc';
import { ListSpec } from '../new_fields/Types';
import { List } from '../new_fields/List';
@@ -12,19 +12,19 @@ const schema1 = createSchema({
hello: "number",
test: "string",
fields: "boolean",
- url: URLField,
+ url: ImageField,
testDoc: Doc
});
-const TestDoc = makeInterface([schema1]);
+const TestDoc = makeInterface(schema1);
type TestDoc = makeInterface<[typeof schema1]>;
const schema2 = createSchema({
- hello: URLField,
+ hello: ImageField,
test: "boolean",
fields: { List: "number" } as ListSpec<number>,
url: "number",
- testDoc: URLField
+ testDoc: ImageField
});
const Test2Doc = makeStrictInterface(schema2);
@@ -43,7 +43,7 @@ const assert = (bool: boolean) => {
class Test extends React.Component {
onClick = () => {
- const url = new URLField(new URL("http://google.com"));
+ const url = new ImageField(new URL("http://google.com"));
const doc = new Doc();
const doc2 = new Doc();
doc.hello = 5;
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 10e8fe7ec..5d18cbb2e 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -33,7 +33,7 @@ export class ObjectField {
export type Field = number | string | boolean | ObjectField | RefField;
export type Opt<T> = T | undefined;
export type FieldWaiting<T extends Field = Field> = Promise<T | undefined>;
-export type FieldValue<T extends Field = Field> = Opt<T> | FieldWaiting<T>;
+export type FieldResult<T extends Field = Field> = Opt<T> | FieldWaiting<T>;
export const Self = Symbol("Self");
@@ -77,7 +77,7 @@ export namespace Doc {
return Cast(field, ctor);
});
}
- export function Get(doc: Doc, key: string, ignoreProto: boolean = false): FieldValue {
+ export function Get(doc: Doc, key: string, ignoreProto: boolean = false): FieldResult {
const self = doc[Self];
return getField(self, key, ignoreProto);
}
diff --git a/src/new_fields/Schema.ts b/src/new_fields/Schema.ts
index 696a5d2a8..3b7078cb0 100644
--- a/src/new_fields/Schema.ts
+++ b/src/new_fields/Schema.ts
@@ -1,13 +1,7 @@
import { Interface, ToInterface, Cast, FieldCtor, ToConstructor, HasTail, Head, Tail } from "./Types";
import { Doc, Field, ObjectField } from "./Doc";
-import { URLField } from "./URLField";
-type All<T extends Interface[], U extends Doc> = {
- 1: makeInterface<[Head<T>], U> & All<Tail<T>, U>,
- 0: makeInterface<[Head<T>], U>
-}[HasTail<T> extends true ? 1 : 0];
-
-type AllToInterface<T extends any[]> = {
+type AllToInterface<T extends Interface[]> = {
1: ToInterface<Head<T>> & AllToInterface<Tail<T>>,
0: ToInterface<Head<T>>
}[HasTail<T> extends true ? 1 : 0];
@@ -16,7 +10,6 @@ export const emptySchema = createSchema({});
export const Document = makeInterface(emptySchema);
export type Document = makeInterface<[typeof emptySchema]>;
-const DocSymbol = Symbol("Doc");
export type makeInterface<T extends Interface[], U extends Doc = Doc> = Partial<AllToInterface<T>> & U;
// export function makeInterface<T extends Interface[], U extends Doc>(schemas: T): (doc: U) => All<T, U>;
// export function makeInterface<T extends Interface, U extends Doc>(schema: T): (doc: U) => makeInterface<T, U>;
@@ -29,26 +22,19 @@ export function makeInterface<T extends Interface[], U extends Doc>(...schemas:
}
const proto = new Proxy({}, {
get(target: any, prop) {
- if (prop === DocSymbol) {
- return target[prop];
- }
- const field = target[DocSymbol][prop];
+ const field = target.doc[prop];
if (prop in schema) {
return Cast(field, (schema as any)[prop]);
}
return field;
},
set(target: any, prop, value) {
- if (prop === DocSymbol) {
- target[prop] = value;
- }
- target[DocSymbol][prop] = value;
+ target.doc[prop] = value;
return true;
}
});
return function (doc: any) {
- const obj = Object.create(proto);
- obj.__doc = doc;
+ const obj = Object.create(proto, { doc: { value: doc, writable: false } });
return obj;
};
}
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index e4d15e276..f4f66fe5c 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -1,4 +1,4 @@
-import { Field, Opt, FieldWaiting, FieldValue } from "./Doc";
+import { Field, Opt, FieldWaiting, FieldResult } from "./Doc";
import { List } from "./List";
export type ToType<T> =
@@ -6,7 +6,8 @@ export type ToType<T> =
T extends "number" ? number :
T extends "boolean" ? boolean :
T extends ListSpec<infer U> ? List<U> :
- T extends { new(...args: any[]): infer R } ? (R | Promise<R>) : never;
+ // T extends { new(...args: any[]): infer R } ? (R | Promise<R>) : never;
+ T extends { new(...args: any[]): infer R } ? R : never;
export type ToConstructor<T> =
T extends string ? "string" :
@@ -35,9 +36,9 @@ export interface Interface {
export type FieldCtor<T extends Field> = T extends List<infer R> ? ListSpec<R> : ToConstructor<T>;
-export function Cast<T extends FieldCtor<Field>>(field: Field | FieldWaiting | undefined, ctor: T): FieldValue<ToType<T>>;
+export function Cast<T extends FieldCtor<Field>>(field: Field | FieldWaiting | undefined, ctor: T): FieldResult<ToType<T>>;
export function Cast<T extends FieldCtor<Field>>(field: Field | FieldWaiting | undefined, ctor: T, defaultVal: ToType<T>): ToType<T>;
-export function Cast<T extends FieldCtor<Field>>(field: Field | FieldWaiting | undefined, ctor: T, defaultVal?: ToType<T>): FieldValue<ToType<T>> | undefined {
+export function Cast<T extends FieldCtor<Field>>(field: Field | FieldWaiting | undefined, ctor: T, defaultVal?: ToType<T>): FieldResult<ToType<T>> | undefined {
if (field instanceof Promise) {
return defaultVal === undefined ? field.then(f => Cast(f, ctor) as any) : defaultVal;
}
@@ -66,6 +67,6 @@ export function FieldValue<T extends Field>(field: Opt<T> | Promise<Opt<T>>, def
export interface PromiseLike<T> {
then(callback: (field: Opt<T> | PromiseLike<T>) => void): void;
}
-export function PromiseValue<T extends Field>(field: FieldValue<T>): PromiseLike<Opt<T>> {
+export function PromiseValue<T extends Field>(field: FieldResult<T>): PromiseLike<Opt<T>> {
return field instanceof Promise ? field : { then(cb: ((field: Opt<T>) => void)) { return cb(field); } };
} \ No newline at end of file
diff --git a/src/new_fields/URLField.ts b/src/new_fields/URLField.ts
index e456a7d16..1da245e73 100644
--- a/src/new_fields/URLField.ts
+++ b/src/new_fields/URLField.ts
@@ -13,7 +13,6 @@ function url() {
);
}
-@Deserializable("url")
export class URLField extends ObjectField {
@serializable(url())
readonly url: URL;
@@ -22,4 +21,10 @@ export class URLField extends ObjectField {
super();
this.url = url;
}
-} \ No newline at end of file
+}
+
+@Deserializable("audio") export class AudioField extends URLField { }
+@Deserializable("image") export class ImageField extends URLField { }
+@Deserializable("video") export class VideoField extends URLField { }
+@Deserializable("pdf") export class PdfField extends URLField { }
+@Deserializable("web") export class WebField extends URLField { } \ No newline at end of file