aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts36
-rw-r--r--src/client/views/Main.tsx31
-rw-r--r--src/client/views/collections/CollectionFreeFormView.tsx6
-rw-r--r--src/client/views/collections/CollectionView.tsx2
-rw-r--r--src/client/views/nodes/AudioBox.scss4
-rw-r--r--src/client/views/nodes/AudioBox.tsx44
-rw-r--r--src/client/views/nodes/DocumentView.tsx4
-rw-r--r--src/client/views/nodes/FieldView.tsx11
-rw-r--r--src/client/views/nodes/VideoBox.scss4
-rw-r--r--src/client/views/nodes/VideoBox.tsx43
-rw-r--r--src/fields/AudioField.ts31
-rw-r--r--src/fields/ListField.ts20
-rw-r--r--src/fields/VideoField.ts30
-rw-r--r--src/server/Message.ts2
-rw-r--r--src/server/ServerUtil.ts35
15 files changed, 274 insertions, 29 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 30a292502..d22e61fb7 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -14,6 +14,11 @@ import { HtmlField } from "../../fields/HtmlField";
import { Key } from "../../fields/Key"
import { Field } from "../../fields/Field";
import { KeyValueBox } from "../views/nodes/KeyValueBox"
+import { KVPField } from "../../fields/KVPField";
+import { VideoField } from "../../fields/VideoField"
+import { VideoBox } from "../views/nodes/VideoBox";
+import { AudioField } from "../../fields/AudioField";
+import { AudioBox } from "../views/nodes/AudioBox";
import { PDFField } from "../../fields/PDFField";
import { PDFBox } from "../views/nodes/PDFBox";
import { CollectionPDFView } from "../views/collections/CollectionPDFView";
@@ -40,6 +45,8 @@ export namespace Documents {
let webProto: Document;
let collProto: Document;
let kvpProto: Document;
+ let videoProto: Document;
+ let audioProto: Document;
let pdfProto: Document;
const textProtoId = "textProto";
const pdfProtoId = "pdfProto";
@@ -47,6 +54,8 @@ export namespace Documents {
const webProtoId = "webProto";
const collProtoId = "collectionProto";
const kvpProtoId = "kvpProto";
+ const videoProtoId = "videoProto"
+ const audioProtoId = "audioProto";
export function initProtos(mainDocId: string, callback: (mainDoc?: Document) => void) {
Server.GetFields([collProtoId, textProtoId, imageProtoId, mainDocId], (fields) => {
@@ -121,6 +130,17 @@ export namespace Documents {
kvpProto = setupPrototypeOptions(kvpProtoId, "KVP_PROTO", KeyValueBox.LayoutString(),
{ x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] })
}
+ function GetVideoPrototype(): Document {
+ return videoProto ? videoProto :
+ videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", VideoBox.LayoutString(),
+ { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] })
+ }
+ function GetAudioPrototype(): Document {
+ return audioProto ? audioProto :
+ audioProto = setupPrototypeOptions(audioProtoId, "AUDIO_PROTO", AudioBox.LayoutString(),
+ { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] })
+ }
+
export function ImageDocument(url: string, options: DocumentOptions = {}) {
let doc = SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] },
@@ -130,6 +150,22 @@ export namespace Documents {
// doc.SetText(KeyStore.OverlayLayout, FixedCaption());
return doc;
}
+ export function VideoDocument(url: string, options: DocumentOptions = {}){
+ let doc = SetInstanceOptions(GetVideoPrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] },
+ new URL(url), VideoField);
+ doc.SetText(KeyStore.Caption, "my caption...");
+ doc.SetText(KeyStore.BackgroundLayout, EmbeddedCaption());
+ doc.SetText(KeyStore.OverlayLayout, FixedCaption());
+ return doc;
+ }
+ export function AudioDocument(url: string, options: DocumentOptions = {}){
+ let doc = SetInstanceOptions(GetAudioPrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] },
+ new URL(url), AudioField);
+ doc.SetText(KeyStore.Caption, "my caption...");
+ doc.SetText(KeyStore.BackgroundLayout, EmbeddedCaption());
+ doc.SetText(KeyStore.OverlayLayout, FixedCaption());
+ return doc;
+ }
export function TextDocument(options: DocumentOptions = {}) {
return SetInstanceOptions(GetTextPrototype(), options, "", TextField);
}
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 79c5cb5aa..e4ef90d97 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -29,6 +29,8 @@ import { faGlobeAsia } from '@fortawesome/free-solid-svg-icons';
import { faUndoAlt } from '@fortawesome/free-solid-svg-icons';
import { faRedoAlt } from '@fortawesome/free-solid-svg-icons';
import { faPenNib } from '@fortawesome/free-solid-svg-icons';
+import { faFilm } from '@fortawesome/free-solid-svg-icons';
+import { faMusic } from '@fortawesome/free-solid-svg-icons';
configure({ enforceActions: "observed" }); // causes errors to be generated when modifying an observable outside of an action
@@ -53,6 +55,8 @@ library.add(faGlobeAsia);
library.add(faUndoAlt);
library.add(faRedoAlt);
library.add(faPenNib);
+library.add(faFilm);
+library.add(faMusic);
Documents.initProtos(mainDocId, (res?: Document) => {
if (res instanceof Document) {
@@ -75,6 +79,8 @@ Documents.initProtos(mainDocId, (res?: Document) => {
let imgurl = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg";
let pdfurl = "http://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf"
let weburl = "https://cs.brown.edu/courses/cs166/";
+ let audiourl = "http://techslides.com/demos/samples/sample.mp3";
+ let videourl = "http://techslides.com/demos/sample-videos/small.mp4";
let clearDatabase = action(() => Utils.Emit(Server.Socket, MessageStore.DeleteAll, {}))
let addTextNode = action(() => Documents.TextDocument({ width: 230, height: 130, title: "a text note" }))
let addColNode = action(() => Documents.FreeformDocument([], { width: 300, height: 300, title: "a freeform collection" }));
@@ -82,8 +88,8 @@ Documents.initProtos(mainDocId, (res?: Document) => {
let addPDFNode = action(() => Documents.PdfDocument(pdfurl, { width: 300, height: 400, title: "a pdf" }));
let addImageNode = action(() => Documents.ImageDocument(imgurl, { width: 200, height: 200, title: "an image of a cat" }));
let addWebNode = action(() => Documents.WebDocument(weburl, { width: 300, height: 400, title: "a sample web page" }));
-
-
+ let addVideoNode = action(() => Documents.VideoDocument(videourl, { width: 300, height: 250, title: "video node" }));
+ let addAudioNode = action(() => Documents.AudioDocument(audiourl, { width: 250, height: 100, title: "audio node" }));
let addClick = (creator: () => Document) => action(() =>
mainfreeform.GetList<Document>(KeyStore.Data, []).push(creator())
);
@@ -93,11 +99,10 @@ Documents.initProtos(mainDocId, (res?: Document) => {
let webRef = React.createRef<HTMLDivElement>();
let textRef = React.createRef<HTMLDivElement>();
let schemaRef = React.createRef<HTMLDivElement>();
+ let videoRef = React.createRef<HTMLDivElement>();
+ let audioRef = React.createRef<HTMLDivElement>();
let colRef = React.createRef<HTMLDivElement>();
- // fontawesome stuff
- library.add()
-
ReactDOM.render((
<div style={{ position: "absolute", width: "100%", height: "100%" }}>
{/* <div id="dash-title">— DASH —</div> */}
@@ -116,15 +121,15 @@ Documents.initProtos(mainDocId, (res?: Document) => {
<button className="clear-db-button" onClick={clearDatabase}>Clear Database</button>
{/* @TODO this should really be moved into a moveable toolbar component, but for now let's put it here to meet the deadline */}
- <div id="toolbar">
+ < div id="toolbar" >
<button className="toolbar-button round-button" title="Undo" onClick={() => UndoManager.Undo()}><FontAwesomeIcon icon="undo-alt" size="sm" /></button>
<button className="toolbar-button round-button" title="Redo" onClick={() => UndoManager.Redo()}><FontAwesomeIcon icon="redo-alt" size="sm" /></button>
{/* @TODO do the ink thing */}
- <button className="toolbar-button round-button" title="Ink"><FontAwesomeIcon icon="pen-nib" size="sm" /></button>
- </div>
+ < button className="toolbar-button round-button" title="Ink" > <FontAwesomeIcon icon="pen-nib" size="sm" /></button >
+ </div >
{/* for the expandable add nodes menu. Not included with the above because once it expands it expands the whole div with it, making canvas interactions limited. */}
- <div id="add-nodes-menu">
+ < div id="add-nodes-menu" >
<input type="checkbox" id="add-menu-toggle" />
<label htmlFor="add-menu-toggle" title="Add Node"><p>+</p></label>
@@ -139,6 +144,12 @@ Documents.initProtos(mainDocId, (res?: Document) => {
<li><div ref={pdfRef}><button className="round-button add-button" title="Add PDF" onPointerDown={setupDrag(pdfRef, addPDFNode)} onClick={addClick(addPDFNode)}>
<FontAwesomeIcon icon="file-pdf" size="sm" />
</button></div></li>
+ <li><div ref={videoRef}><button className="round-button add-button" title="Add Video" onPointerDown={setupDrag(videoRef, addVideoNode)} onClick={addClick(addVideoNode)}>
+ <FontAwesomeIcon icon="film" size="sm" />
+ </button></div></li>
+ <li><div ref={audioRef}><button className="round-button add-button" title="Add Audio" onPointerDown={setupDrag(audioRef, addAudioNode)} onClick={addClick(addAudioNode)}>
+ <FontAwesomeIcon icon="music" size="sm" />
+ </button></div></li>
<li><div ref={webRef}><button className="round-button add-button" title="Add Web Clipping" onPointerDown={setupDrag(webRef, addWebNode)} onClick={addClick(addWebNode)}>
<FontAwesomeIcon icon="globe-asia" size="sm" />
</button></div></li>
@@ -151,7 +162,7 @@ Documents.initProtos(mainDocId, (res?: Document) => {
</ul>
</div>
- </div>
+ </div >
{/* <InkingControl /> */}
</div >),
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 782313e55..16002ad9f 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -1,4 +1,4 @@
-import { action, computed, observable } from "mobx";
+import { action, computed, observable, reaction, trace } from "mobx";
import { observer } from "mobx-react";
import { Document } from "../../../fields/Document";
import { FieldWaiting } from "../../../fields/Field";
@@ -25,6 +25,7 @@ import "./CollectionFreeFormView.scss";
import { COLLECTION_BORDER_WIDTH } from "./CollectionView";
import { CollectionViewBase } from "./CollectionViewBase";
import React = require("react");
+import { render } from "pug";
const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this?
@observer
@@ -282,7 +283,6 @@ export class CollectionFreeFormView extends CollectionViewBase {
}
render() {
-
//determines whether preview text cursor should be visible (ie when user taps this collection it should)
let cursor = null;
if (this._previewCursorVisible) {
@@ -319,4 +319,4 @@ export class CollectionFreeFormView extends CollectionViewBase {
</div>
);
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 159d7f3e0..932ca29a9 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -116,4 +116,4 @@ export class CollectionView extends React.Component<CollectionViewProps> {
{this.subView}
</div>)
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss
new file mode 100644
index 000000000..704cdc31c
--- /dev/null
+++ b/src/client/views/nodes/AudioBox.scss
@@ -0,0 +1,4 @@
+.audiobox-cont{
+ height: 100%;
+ width: 100%;
+} \ No newline at end of file
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
new file mode 100644
index 000000000..f7d89843d
--- /dev/null
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -0,0 +1,44 @@
+import React = require("react")
+import { FieldViewProps, FieldView } from './FieldView';
+import { FieldWaiting } from '../../../fields/Field';
+import { observer } from "mobx-react"
+import { ContextMenu } from "../../views/ContextMenu";
+import { observable, action } from 'mobx';
+import { KeyStore } from '../../../fields/KeyStore';
+import { AudioField } from "../../../fields/AudioField";
+import "./AudioBox.scss"
+import { NumberField } from "../../../fields/NumberField";
+
+@observer
+export class AudioBox extends React.Component<FieldViewProps> {
+
+ public static LayoutString() { return FieldView.LayoutString(AudioBox) }
+
+ constructor(props: FieldViewProps) {
+ super(props);
+ }
+
+
+
+ componentDidMount() {
+ }
+
+ componentWillUnmount() {
+ }
+
+
+ render() {
+ let field = this.props.doc.Get(this.props.fieldKey)
+ let path = field == FieldWaiting ? "http://techslides.com/demos/samples/sample.mp3":
+ field instanceof AudioField ? field.Data.href : "http://techslides.com/demos/samples/sample.mp3";
+
+ return (
+ <div>
+ <audio controls className = "audiobox-cont">
+ <source src = {path} type="audio/mpeg"/>
+ Not supported.
+ </audio>
+ </div>
+ )
+ }
+} \ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 41e93df35..263bb31d7 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -16,6 +16,8 @@ import { CollectionPDFView } from "../collections/CollectionPDFView";
import { ContextMenu } from "../ContextMenu";
import { FormattedTextBox } from "../nodes/FormattedTextBox";
import { ImageBox } from "../nodes/ImageBox";
+import { VideoBox } from "../nodes/VideoBox";
+import { AudioBox } from "../nodes/AudioBox";
import { Documents } from "../../documents/Documents"
import { KeyValueBox } from "./KeyValueBox"
import { WebBox } from "../nodes/WebBox";
@@ -196,7 +198,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
}
@computed get mainContent() {
return <JsxParser
- components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, WebBox, KeyValueBox, PDFBox }}
+ components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, WebBox, KeyValueBox, VideoBox, AudioBox, PDFBox }}
bindings={this._documentBindings}
jsx={this.layout}
showWarnings={true}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 9e63006d1..49f4cefce 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -8,10 +8,15 @@ import { NumberField } from "../../../fields/NumberField";
import { RichTextField } from "../../../fields/RichTextField";
import { ImageField } from "../../../fields/ImageField";
import { WebField } from "../../../fields/WebField";
+import { VideoField } from "../../../fields/VideoField"
import { Key } from "../../../fields/Key";
import { FormattedTextBox } from "./FormattedTextBox";
import { ImageBox } from "./ImageBox";
import { WebBox } from "./WebBox";
+import { VideoBox } from "./VideoBox";
+import { AudioBox } from "./AudioBox";
+import { AudioField } from "../../../fields/AudioField";
+
//
// these properties get assigned through the render() method of the DocumentView when it creates this node.
@@ -55,6 +60,12 @@ export class FieldView extends React.Component<FieldViewProps> {
}
else if (field instanceof WebField) {
return <WebBox {...this.props} />
+ }
+ else if (field instanceof VideoField){
+ return <VideoBox {...this.props}/>
+ }
+ else if (field instanceof AudioField){
+ return <AudioBox {...this.props}/>
}
// bcz: this belongs here, but it doesn't render well so taking it out for now
// else if (field instanceof HtmlField) {
diff --git a/src/client/views/nodes/VideoBox.scss b/src/client/views/nodes/VideoBox.scss
new file mode 100644
index 000000000..7306450d9
--- /dev/null
+++ b/src/client/views/nodes/VideoBox.scss
@@ -0,0 +1,4 @@
+.videobox-cont{
+ width: 100%;
+ height: 100%;
+} \ No newline at end of file
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
new file mode 100644
index 000000000..22ff5c5ad
--- /dev/null
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -0,0 +1,43 @@
+import React = require("react")
+import { FieldViewProps, FieldView } from './FieldView';
+import { FieldWaiting } from '../../../fields/Field';
+import { observer } from "mobx-react"
+import { VideoField } from '../../../fields/VideoField';
+import "./VideoBox.scss"
+import { ContextMenu } from "../../views/ContextMenu";
+import { observable, action } from 'mobx';
+import { KeyStore } from '../../../fields/KeyStore';
+
+@observer
+export class VideoBox extends React.Component<FieldViewProps> {
+
+ public static LayoutString() { return FieldView.LayoutString(VideoBox) }
+
+ constructor(props: FieldViewProps) {
+ super(props);
+ }
+
+
+
+ componentDidMount() {
+ }
+
+ componentWillUnmount() {
+ }
+
+
+ render() {
+ let field = this.props.doc.Get(this.props.fieldKey)
+ let path = field == FieldWaiting ? "http://techslides.com/demos/sample-videos/small.mp4":
+ field instanceof VideoField ? field.Data.href : "http://techslides.com/demos/sample-videos/small.mp4";
+
+ return (
+ <div>
+ <video width = {200} height = {200} controls className = "videobox-cont">
+ <source src = {path} type = "video/mp4"/>
+ Not supported.
+ </video>
+ </div>
+ )
+ }
+} \ No newline at end of file
diff --git a/src/fields/AudioField.ts b/src/fields/AudioField.ts
new file mode 100644
index 000000000..aefcc15c1
--- /dev/null
+++ b/src/fields/AudioField.ts
@@ -0,0 +1,31 @@
+import { BasicField } from "./BasicField";
+import { Field, FieldId } from "./Field";
+import { Types } from "../server/Message";
+
+export class AudioField extends BasicField<URL> {
+ constructor(data: URL | undefined = undefined, id?: FieldId, save: boolean = true) {
+ super(data == undefined ? new URL("http://techslides.com/demos/samples/sample.mp3") : data, save, id);
+ }
+
+ toString(): string {
+ return this.Data.href;
+ }
+
+
+ ToScriptString(): string {
+ return `new AudioField("${this.Data}")`;
+ }
+
+ Copy(): Field {
+ return new AudioField(this.Data);
+ }
+
+ ToJson(): { type: Types, data: URL, _id: string } {
+ return {
+ type: Types.Audio,
+ data: this.Data,
+ _id: this.Id
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/fields/ListField.ts b/src/fields/ListField.ts
index a71325a65..ce32da0a6 100644
--- a/src/fields/ListField.ts
+++ b/src/fields/ListField.ts
@@ -70,7 +70,25 @@ export class ListField<T extends Field> extends BasicField<T[]> {
init(callback: (field: Field) => any) {
Server.GetFields(this._proxies, action((fields: { [index: string]: Field }) => {
if (!this.arraysEqual(this._proxies, this.Data.map(field => field.Id))) {
- this.data = this._proxies.map(id => fields[id] as T)
+ var dataids = this.data.map(d => d.Id);
+ var added = this.data.length == this._proxies.length - 1;
+ var deleted = this.data.length > this._proxies.length;
+ for (let i = 0; i < dataids.length && added; i++)
+ added = this._proxies.indexOf(dataids[i]) != -1;
+ for (let i = 0; i < this._proxies.length && deleted; i++)
+ deleted = dataids.indexOf(this._proxies[i]) != -1;
+ if (added) { // if only 1 items was added
+ for (let i = 0; i < this._proxies.length; i++)
+ if (dataids.indexOf(this._proxies[i]) === -1)
+ this.Data.splice(i, 0, fields[this._proxies[i]] as T);
+ } else if (deleted) { // if only items were deleted
+ for (let i = this.data.length - 1; i >= 0; i--) {
+ if (this._proxies.indexOf(this.data[i].Id) === -1) {
+ this.Data.splice(i, 1);
+ }
+ }
+ } else // otherwise, just rebuild the whole list
+ this.data = this._proxies.map(id => fields[id] as T)
observe(this.Data, () => {
this.updateProxies()
Server.UpdateField(this);
diff --git a/src/fields/VideoField.ts b/src/fields/VideoField.ts
new file mode 100644
index 000000000..5f4ae19bf
--- /dev/null
+++ b/src/fields/VideoField.ts
@@ -0,0 +1,30 @@
+import { BasicField } from "./BasicField";
+import { Field, FieldId } from "./Field";
+import { Types } from "../server/Message";
+
+export class VideoField extends BasicField<URL> {
+ constructor(data: URL | undefined = undefined, id?: FieldId, save: boolean = true) {
+ super(data == undefined ? new URL("http://techslides.com/demos/sample-videos/small.mp4") : data, save, id);
+ }
+
+ toString(): string {
+ return this.Data.href;
+ }
+
+ ToScriptString(): string {
+ return `new VideoField("${this.Data}")`;
+ }
+
+ Copy(): Field {
+ return new VideoField(this.Data);
+ }
+
+ ToJson(): { type: Types, data: URL, _id: string } {
+ return {
+ type: Types.Video,
+ data: this.Data,
+ _id: this.Id
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/server/Message.ts b/src/server/Message.ts
index 5e97a5edf..8a00f6b59 100644
--- a/src/server/Message.ts
+++ b/src/server/Message.ts
@@ -45,7 +45,7 @@ export class GetFieldArgs {
}
export enum Types {
- Number, List, Key, Image, Web, Document, Text, RichText, DocumentReference, Html, Ink, PDF
+ Number, List, Key, Image, Web, Document, Text, RichText, DocumentReference, Html, Video, Audio, Ink, PDF
}
export class DocumentTransfer implements Transferable {
diff --git a/src/server/ServerUtil.ts b/src/server/ServerUtil.ts
index 3b9d14891..5331c9e30 100644
--- a/src/server/ServerUtil.ts
+++ b/src/server/ServerUtil.ts
@@ -1,17 +1,24 @@
-import {HtmlField} from '../fields/HtmlField';
+
+import { Field } from './../fields/Field';
+import { TextField } from './../fields/TextField';
+import { NumberField } from './../fields/NumberField';
+import { RichTextField } from './../fields/RichTextField';
+import { Key } from './../fields/Key';
+import { ImageField } from './../fields/ImageField';
+import { ListField } from './../fields/ListField';
+import { Document } from './../fields/Document';
+import { Server } from './../client/Server';
+import { Types } from './Message';
+import { Utils } from '../Utils';
+import { HtmlField } from '../fields/HtmlField';
+import { WebField } from '../fields/WebField';
+import { AudioField } from '../fields/AudioField';
+import { VideoField } from '../fields/VideoField';
import {InkField} from '../fields/InkField';
import {PDFField} from '../fields/PDFField';
-import {WebField} from '../fields/WebField';
-import {Utils} from '../Utils';
-import {Document} from './../fields/Document';
-import {Field} from './../fields/Field';
-import {ImageField} from './../fields/ImageField';
-import {Key} from './../fields/Key';
-import {ListField} from './../fields/ListField';
-import {NumberField} from './../fields/NumberField';
-import {RichTextField} from './../fields/RichTextField';
-import {TextField} from './../fields/TextField';
-import {Types} from './Message';
+
+
+
export class ServerUtils {
public static FromJson(json: any): Field {
@@ -44,6 +51,10 @@ export class ServerUtils {
return new PDFField(new URL(data), id, false)
case Types.List:
return ListField.FromJson(id, data)
+ case Types.Audio:
+ return new AudioField(new URL(data), id, false)
+ case Types.Video:
+ return new VideoField(new URL(data), id, false)
case Types.Ink:
return InkField.FromJson(id, data);
case Types.Document: