diff options
| author | Tyler Schicke <tyler_schicke@brown.edu> | 2019-04-21 23:40:48 -0400 |
|---|---|---|
| committer | Tyler Schicke <tyler_schicke@brown.edu> | 2019-04-21 23:40:48 -0400 |
| commit | 393d351420b3a0d28f4cd1ea8b674fa5d04bfcde (patch) | |
| tree | 27f663e4e034949d742294259e021e9826fb0631 /src | |
| parent | fd5c4f18d0af6571508f142ca400e6d752f19800 (diff) | |
More fixes
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/views/collections/CollectionDockingView.tsx | 6 | ||||
| -rw-r--r-- | src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/FieldView.tsx | 8 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 15 | ||||
| -rw-r--r-- | src/client/views/nodes/VideoBox.tsx | 35 | ||||
| -rw-r--r-- | src/client/views/nodes/WebBox.tsx | 4 | ||||
| -rw-r--r-- | src/debug/Test.tsx | 12 | ||||
| -rw-r--r-- | src/new_fields/Doc.ts | 4 | ||||
| -rw-r--r-- | src/new_fields/Schema.ts | 22 | ||||
| -rw-r--r-- | src/new_fields/Types.ts | 11 | ||||
| -rw-r--r-- | src/new_fields/URLField.ts | 9 |
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 |
