From d7a3ba60aa2e9363eb1f9ad8ac2245395e2c6b70 Mon Sep 17 00:00:00 2001
From: Jude <julie_wang1@brown.edu>
Date: Sat, 9 Mar 2019 11:41:50 -0500
Subject: minor improvements

---
 src/client/views/collections/CollectionView.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/collections/CollectionView.tsx')

diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 49df04163..159d7f3e0 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -22,7 +22,7 @@ export enum CollectionViewType {
     Tree
 }
 
-export const COLLECTION_BORDER_WIDTH = 2;
+export const COLLECTION_BORDER_WIDTH = 1;
 
 @observer
 export class CollectionView extends React.Component<CollectionViewProps> {
-- 
cgit v1.2.3-70-g09d2


From b9cfa458a6535e7ee0ff8b81398afa1e123cf458 Mon Sep 17 00:00:00 2001
From: Andrew Kim <andrewdkim@users.noreply.github.com>
Date: Sat, 9 Mar 2019 18:21:06 -0500
Subject: added audio and video nodes

---
 src/client/documents/Documents.ts               | 35 ++++++++++++++++++++
 src/client/views/Main.tsx                       | 11 ++++++-
 src/client/views/collections/CollectionView.tsx |  2 ++
 src/client/views/nodes/AudioBox.scss            |  4 +++
 src/client/views/nodes/AudioBox.tsx             | 44 +++++++++++++++++++++++++
 src/client/views/nodes/DocumentView.tsx         |  4 ++-
 src/client/views/nodes/FieldView.tsx            | 11 +++++++
 src/client/views/nodes/VideoBox.scss            |  4 +++
 src/client/views/nodes/VideoBox.tsx             | 43 ++++++++++++++++++++++++
 src/fields/AudioField.ts                        | 31 +++++++++++++++++
 src/fields/VideoField.ts                        | 30 +++++++++++++++++
 src/server/Message.ts                           |  2 +-
 src/server/ServerUtil.ts                        |  6 ++++
 13 files changed, 224 insertions(+), 3 deletions(-)
 create mode 100644 src/client/views/nodes/AudioBox.scss
 create mode 100644 src/client/views/nodes/AudioBox.tsx
 create mode 100644 src/client/views/nodes/VideoBox.scss
 create mode 100644 src/client/views/nodes/VideoBox.tsx
 create mode 100644 src/fields/AudioField.ts
 create mode 100644 src/fields/VideoField.ts

(limited to 'src/client/views/collections/CollectionView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 1d24ff7d2..f81ad3188 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -15,6 +15,10 @@ 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";
 
 export interface DocumentOptions {
     x?: number;
@@ -38,11 +42,15 @@ export namespace Documents {
     let webProto: Document;
     let collProto: Document;
     let kvpProto: Document;
+    let videoProto: Document; 
+    let audioProto: Document; 
     const textProtoId = "textProto";
     const imageProtoId = "imageProto";
     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) => {
@@ -108,6 +116,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] },
@@ -117,6 +136,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 d845fa7a3..a52047631 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -52,13 +52,16 @@ Documents.initProtos(mainDocId, (res?: Document) => {
 
     let imgurl = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg";
     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: 200, height: 200, title: "a text note" }))
     let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, title: "a freeform collection" }));
     let addSchemaNode = action(() => Documents.SchemaDocument([Documents.TextDocument()], { width: 200, height: 200, title: "a schema collection" }));
+    let addVideoNode = action(() => Documents.VideoDocument(videourl, {width: 200, height:200, title: "video node"})); 
     let addImageNode = action(() => Documents.ImageDocument(imgurl, { width: 200, height: 200, title: "an image of a cat" }));
     let addWebNode = action(() => Documents.WebDocument(weburl, { width: 200, height: 200, title: "a sample web page" }));
-
+    let addAudioNode = action(() => Documents.AudioDocument(audiourl,{ width: 200, height: 200, title: "audio node" } ))
     let addClick = (creator: () => Document) => action(() =>
         mainfreeform.GetList<Document>(KeyStore.Data, []).push(creator())
     );
@@ -67,6 +70,8 @@ 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>();
 
     ReactDOM.render((
@@ -94,6 +99,10 @@ Documents.initProtos(mainDocId, (res?: Document) => {
                 <button onPointerDown={setupDrag(schemaRef, addSchemaNode)} onClick={addClick(addSchemaNode)}>Add Schema</button></div>
             <div className="main-buttonDiv" style={{ bottom: '125px' }} >
                 <button onClick={clearDatabase}>Clear Database</button></div>
+            <div className="main-buttonDiv" style={{ bottom: '150px' }} ref={videoRef}>
+                <button onPointerDown={setupDrag(videoRef, addVideoNode)} onClick={addClick(addVideoNode)}>Add Video</button></div>
+            <div className="main-buttonDiv" style={{ bottom: '175px' }} ref={audioRef}>
+                <button onPointerDown={setupDrag(audioRef, addAudioNode)} onClick={addClick(addAudioNode)}>Add Audio</button></div>
             <button className="main-undoButtons" style={{ bottom: '25px' }} onClick={() => UndoManager.Undo()}>Undo</button>
             <button className="main-undoButtons" style={{ bottom: '0px' }} onClick={() => UndoManager.Redo()}>Redo</button>
         </div>),
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 31824763d..454d547ef 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -19,6 +19,8 @@ export enum CollectionViewType {
     Freeform,
     Schema,
     Docking,
+    Video, 
+    Audio,
     Tree
 }
 
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 e01e1d4cd..b22435f1a 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -15,6 +15,8 @@ import { CollectionView, CollectionViewType } from "../collections/CollectionVie
 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";
@@ -194,7 +196,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     }
     @computed get mainContent() {
         return <JsxParser
-            components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox }}
+            components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox, VideoBox, AudioBox }}
             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/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 148e6e723..f85f56dd2 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
+    Number, List, Key, Image, Web, Document, Text, RichText, DocumentReference, Html, Video, Audio
 }
 
 export class DocumentTransfer implements Transferable {
diff --git a/src/server/ServerUtil.ts b/src/server/ServerUtil.ts
index a53fb5d2b..2e681fece 100644
--- a/src/server/ServerUtil.ts
+++ b/src/server/ServerUtil.ts
@@ -11,6 +11,8 @@ 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';
 
 export class ServerUtils {
     public static FromJson(json: any): Field {
@@ -41,6 +43,10 @@ export class ServerUtils {
                 return new ImageField(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.Document:
                 let doc: Document = new Document(id, false)
                 let fields: [string, string][] = data as [string, string][]
-- 
cgit v1.2.3-70-g09d2


From ebe101203788d9fc564671cc38f085c3ef990536 Mon Sep 17 00:00:00 2001
From: tschicke-brown <tyler_schicke@brown.edu>
Date: Sat, 9 Mar 2019 19:09:06 -0500
Subject: Update CollectionView.tsx

---
 src/client/views/collections/CollectionView.tsx | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

(limited to 'src/client/views/collections/CollectionView.tsx')

diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index fca32e615..f154909bb 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -19,8 +19,6 @@ export enum CollectionViewType {
     Freeform,
     Schema,
     Docking,
-    Video, 
-    Audio,
     Tree
 }
 
@@ -118,4 +116,4 @@ export class CollectionView extends React.Component<CollectionViewProps> {
             {this.subView}
         </div>)
     }
-}
\ No newline at end of file
+}
-- 
cgit v1.2.3-70-g09d2


From 933cfacdeed99da38070790c5ec17cbdeb755267 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 11 Mar 2019 12:54:32 -0400
Subject: added marquee selection.

---
 .../views/collections/CollectionFreeFormView.tsx   | 16 +++++++++++---
 src/client/views/collections/CollectionPDFView.tsx |  2 ++
 src/client/views/collections/CollectionView.tsx    |  7 ++++--
 src/client/views/nodes/DocumentView.tsx            | 25 +++++++++++++++++++---
 4 files changed, 42 insertions(+), 8 deletions(-)

(limited to 'src/client/views/collections/CollectionView.tsx')

diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index bc6d02757..37b3d6adb 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -27,6 +27,7 @@ import { CollectionViewBase } from "./CollectionViewBase";
 import React = require("react");
 import { Utils } from "../../../Utils";
 import { SelectionManager } from "../../util/SelectionManager";
+import anymatch = require("anymatch");
 const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this?
 
 @observer
@@ -115,12 +116,22 @@ export class CollectionFreeFormView extends CollectionViewBase {
 
     }
 
+    intersectRect(r1: { left: number, right: number, top: number, bottom: number },
+        r2: { left: number, right: number, top: number, bottom: number }) {
+        return !(r2.left > r1.right ||
+            r2.right < r1.left ||
+            r2.top > r1.bottom ||
+            r2.bottom < r1.top);
+    }
+
     @action
     marqueeSelect() {
         var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1);
         let p = this.getTransform().transformPoint(this._downX, this._downY);
         let v = this.getTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY);
+        let selRect = { left: p[0], top: p[1], right: p[0] + v[0], bottom: p[1] + v[1] }
 
+        this.props.CollectionView.SelectedDocs.length = 0;
         var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1);
         const lvalue = this.props.Document.GetT<ListField<Document>>(this.props.fieldKey, ListField);
         if (lvalue && lvalue != FieldWaiting) {
@@ -131,9 +142,8 @@ export class CollectionFreeFormView extends CollectionViewBase {
                     var y = doc.GetNumber(KeyStore.Y, 0);
                     var w = doc.GetNumber(KeyStore.Width, 0);
                     var h = doc.GetNumber(KeyStore.Height, 0);
-                    if (x > p[0] && x < p[0] + v[0] && y > p[1] && y < p[1] + v[1]) {
-                        // SelectionManager.SelectDoc(doc as any as DocumentView, true);
-                    }
+                    if (this.intersectRect({ left: x, top: y, right: x + w, bottom: y + h }, selRect))
+                        this.props.CollectionView.SelectedDocs.push(doc.Id)
                 }
             })
         }
diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx
index 7fd9f0f11..f22c07060 100644
--- a/src/client/views/collections/CollectionPDFView.tsx
+++ b/src/client/views/collections/CollectionPDFView.tsx
@@ -6,6 +6,7 @@ import { ContextMenu } from "../ContextMenu";
 import { CollectionView, CollectionViewType } from "./CollectionView";
 import { CollectionViewProps } from "./CollectionViewBase";
 import React = require("react");
+import { FieldId } from "../../../fields/Field";
 
 
 @observer
@@ -17,6 +18,7 @@ export class CollectionPDFView extends React.Component<CollectionViewProps> {
                     isTopMost={isTopMost} SelectOnLoad={selectOnLoad} BackgroundView={BackgroundView} focus={focus}/>`;
     }
 
+    public SelectedDocs: FieldId[] = []
     @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : 0;
     @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : 0;
 
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index f154909bb..548a51bf1 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";
@@ -12,7 +12,7 @@ import { CollectionDockingView } from "./CollectionDockingView";
 import { CollectionSchemaView } from "./CollectionSchemaView";
 import { CollectionViewProps } from "./CollectionViewBase";
 import { CollectionTreeView } from "./CollectionTreeView";
-import { Field } from "../../../fields/Field";
+import { Field, FieldId } from "../../../fields/Field";
 
 export enum CollectionViewType {
     Invalid,
@@ -27,6 +27,9 @@ export const COLLECTION_BORDER_WIDTH = 2;
 @observer
 export class CollectionView extends React.Component<CollectionViewProps> {
 
+    @observable
+    public SelectedDocs: FieldId[] = [];
+
     public static LayoutString(fieldKey: string = "DataKey") {
         return `<${CollectionView.name} Document={Document}
                     ScreenToLocalTransform={ScreenToLocalTransform} fieldKey={${fieldKey}} panelWidth={PanelWidth} panelHeight={PanelHeight} isSelected={isSelected} select={select} bindings={bindings}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 263bb31d7..7627fbf6c 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,4 +1,4 @@
-import { action, computed } from "mobx";
+import { action, computed, IReactionDisposer, reaction } from "mobx";
 import { observer } from "mobx-react";
 import { Document } from "../../../fields/Document";
 import { Field, FieldWaiting, Opt } from "../../../fields/Field";
@@ -16,8 +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 { VideoBox } from "../nodes/VideoBox";
+import { AudioBox } from "../nodes/AudioBox";
 import { Documents } from "../../documents/Documents"
 import { KeyValueBox } from "./KeyValueBox"
 import { WebBox } from "../nodes/WebBox";
@@ -88,6 +88,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
     private _documentBindings: any = null;
     private _downX: number = 0;
     private _downY: number = 0;
+    private _reactionDisposer: Opt<IReactionDisposer>;
     @computed get active(): boolean { return SelectionManager.IsSelected(this) || !this.props.ContainingCollectionView || this.props.ContainingCollectionView.active(); }
     @computed get topMost(): boolean { return !this.props.ContainingCollectionView || this.props.ContainingCollectionView.collectionViewType == CollectionViewType.Docking; }
     @computed get layout(): string { return this.props.Document.GetText(KeyStore.Layout, "<p>Error loading layout data</p>"); }
@@ -113,6 +114,24 @@ export class DocumentView extends React.Component<DocumentViewProps> {
             }
         }
     }
+
+
+    componentDidMount() {
+        this._reactionDisposer = reaction(
+            () => this.props.ContainingCollectionView && this.props.ContainingCollectionView.SelectedDocs.slice(),
+            () => {
+                if (this.props.ContainingCollectionView && this.props.ContainingCollectionView.SelectedDocs.indexOf(this.props.Document.Id) != -1)
+                    SelectionManager.SelectDoc(this, true);
+            });
+    }
+
+    componentWillUnmount() {
+        if (this._reactionDisposer) {
+            this._reactionDisposer();
+        }
+    }
+
+
     onPointerMove = (e: PointerEvent): void => {
         if (e.cancelBubble) {
             return;
-- 
cgit v1.2.3-70-g09d2


From 31bb06320481ce6fc1dd0de11610d0efcc008866 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 11 Mar 2019 20:20:14 -0400
Subject: removed Docking option

---
 src/client/views/collections/CollectionView.tsx | 1 -
 1 file changed, 1 deletion(-)

(limited to 'src/client/views/collections/CollectionView.tsx')

diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 548a51bf1..17a0fbd23 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -99,7 +99,6 @@ export class CollectionView extends React.Component<CollectionViewProps> {
             ContextMenu.Instance.addItem({ description: "Freeform", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform) })
             ContextMenu.Instance.addItem({ description: "Schema", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Schema) })
             ContextMenu.Instance.addItem({ description: "Treeview", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Tree) })
-            ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) })
         }
     }
 
-- 
cgit v1.2.3-70-g09d2


From 41f458fb4f383bfbf8d5b651189c2f4731262ff8 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 13 Mar 2019 20:33:51 -0400
Subject: added annotations for videos.  added custom play controls for videos.

---
 src/client/documents/Documents.ts                  |  5 +-
 src/client/views/InkingCanvas.tsx                  |  6 +-
 .../views/collections/CollectionFreeFormView.tsx   |  8 +--
 src/client/views/collections/CollectionPDFView.tsx | 13 ++--
 .../views/collections/CollectionVideoView.scss     | 35 +++++++++
 .../views/collections/CollectionVideoView.tsx      | 83 +++++++++++++++++++---
 src/client/views/collections/CollectionView.tsx    |  2 +-
 src/client/views/nodes/PDFBox.tsx                  |  2 +-
 src/client/views/nodes/VideoBox.tsx                |  2 +-
 src/fields/KeyStore.ts                             |  1 -
 10 files changed, 126 insertions(+), 31 deletions(-)
 create mode 100644 src/client/views/collections/CollectionVideoView.scss

(limited to 'src/client/views/collections/CollectionView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index f35d553b1..15e16a491 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -23,6 +23,7 @@ import { PDFField } from "../../fields/PDFField";
 import { PDFBox } from "../views/nodes/PDFBox";
 import { CollectionPDFView } from "../views/collections/CollectionPDFView";
 import { RichTextField } from "../../fields/RichTextField";
+import { CollectionVideoView } from "../views/collections/CollectionVideoView";
 
 export interface DocumentOptions {
     x?: number;
@@ -138,9 +139,9 @@ export namespace Documents {
     }
     function GetVideoPrototype(): Document {
         if (!videoProto) {
-            videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionView.LayoutString("AnnotationsKey"),
+            videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", CollectionVideoView.LayoutString("AnnotationsKey"),
                 { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] });
-            videoProto.SetNumber(KeyStore.CurFrame, 1);
+            videoProto.SetNumber(KeyStore.CurPage, 0);
             videoProto.SetText(KeyStore.BackgroundLayout, VideoBox.LayoutString());
         }
         return videoProto;
diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx
index 0d87c1239..064d1cba2 100644
--- a/src/client/views/InkingCanvas.tsx
+++ b/src/client/views/InkingCanvas.tsx
@@ -74,7 +74,7 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
                 color: InkingControl.Instance.selectedColor,
                 width: InkingControl.Instance.selectedWidth,
                 tool: InkingControl.Instance.selectedTool,
-                page: this.props.Document.GetNumber(KeyStore.CurPage, 0)
+                page: this.props.Document.GetNumber(KeyStore.CurPage, -1)
             });
         this.inkData = data;
         this._isDrawing = true;
@@ -145,11 +145,11 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
 
         // parse data from server
         let paths: Array<JSX.Element> = []
-        let curPage = this.props.Document.GetNumber(KeyStore.CurPage, 0)
+        let curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1)
         Array.from(lines).map(item => {
             let id = item[0];
             let strokeData = item[1];
-            if (strokeData.page == 0 || strokeData.page == curPage)
+            if (strokeData.page == -1 || strokeData.page == curPage)
                 paths.push(<InkingStroke key={id} id={id}
                     line={strokeData.pathData}
                     color={strokeData.color}
diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx
index 71f429e80..08f3a338b 100644
--- a/src/client/views/collections/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/CollectionFreeFormView.tsx
@@ -52,13 +52,13 @@ export class CollectionFreeFormView extends CollectionViewBase {
     }
 
     public getActiveDocuments = () => {
-        var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1);
+        var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1);
         const lvalue = this.props.Document.GetT<ListField<Document>>(this.props.fieldKey, ListField);
         let active: Document[] = [];
         if (lvalue && lvalue != FieldWaiting) {
             lvalue.Data.map(doc => {
-                var page = doc.GetNumber(KeyStore.Page, 0);
-                if (page == curPage || page == 0) {
+                var page = doc.GetNumber(KeyStore.Page, -1);
+                if (page == curPage || page == -1) {
                     active.push(doc);
                 }
             })
@@ -257,7 +257,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
 
     @computed
     get views() {
-        var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1);
+        var curPage = this.props.Document.GetNumber(KeyStore.CurPage, -1);
         const lvalue = this.props.Document.GetT<ListField<Document>>(this.props.fieldKey, ListField);
         if (lvalue && lvalue != FieldWaiting) {
             return lvalue.Data.map(doc => {
diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx
index f22c07060..91ffc9500 100644
--- a/src/client/views/collections/CollectionPDFView.tsx
+++ b/src/client/views/collections/CollectionPDFView.tsx
@@ -18,13 +18,12 @@ export class CollectionPDFView extends React.Component<CollectionViewProps> {
                     isTopMost={isTopMost} SelectOnLoad={selectOnLoad} BackgroundView={BackgroundView} focus={focus}/>`;
     }
 
-    public SelectedDocs: FieldId[] = []
-    @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : 0;
-    @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : 0;
+    private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, -1); }
+    private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); }
+    @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : -1;
+    @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : -1;
 
-    @computed private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, 0); }
-    @computed private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); }
-    @computed private get uIButtons() {
+    private get uIButtons() {
         return (
             <div className="pdfBox-buttonTray" key="tray">
                 <button className="pdfButton" onClick={this.onPageBack}>{"<"}</button>
@@ -33,7 +32,7 @@ export class CollectionPDFView extends React.Component<CollectionViewProps> {
     }
 
     // "inherited" CollectionView API starts here...
-
+    public SelectedDocs: FieldId[] = []
     public active: () => boolean = () => CollectionView.Active(this);
 
     addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); }
diff --git a/src/client/views/collections/CollectionVideoView.scss b/src/client/views/collections/CollectionVideoView.scss
new file mode 100644
index 000000000..6c2f5a62a
--- /dev/null
+++ b/src/client/views/collections/CollectionVideoView.scss
@@ -0,0 +1,35 @@
+.collectionVideoView-controls{
+    width: 100%;
+    height: 100%;
+    position: absolute;
+}
+.collectionVideoView-time{
+    color : white;
+    top :25px;
+    left : 25px;
+    position: absolute;
+    background-color: rgba(50, 50, 50, 0.2);
+}
+.collectionVideoView-play {
+    width: 25px;
+    height: 20px;
+    bottom: 25px;
+    left : 25px;
+    position: absolute;
+    color : white;
+    background-color: rgba(50, 50, 50, 0.2);
+    border-radius: 4px;
+    text-align: center;
+}
+.collectionVideoView-full {
+    width: 25px;
+    height: 20px;
+    bottom: 25px;
+    right : 25px;
+    position: absolute;
+    color : white;
+    background-color: rgba(50, 50, 50, 0.2);
+    border-radius: 4px;
+    text-align: center;
+
+}
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx
index a6471f53c..058325b21 100644
--- a/src/client/views/collections/CollectionVideoView.tsx
+++ b/src/client/views/collections/CollectionVideoView.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 { KeyStore } from "../../../fields/KeyStore";
@@ -7,6 +7,8 @@ import { CollectionView, CollectionViewType } from "./CollectionView";
 import { CollectionViewProps } from "./CollectionViewBase";
 import React = require("react");
 import { FieldId } from "../../../fields/Field";
+import { ReplaceAroundStep } from "prosemirror-transform";
+import "./CollectionVideoView.scss"
 
 
 @observer
@@ -18,14 +20,10 @@ export class CollectionVideoView extends React.Component<CollectionViewProps> {
                     isTopMost={isTopMost} SelectOnLoad={selectOnLoad} BackgroundView={BackgroundView} focus={focus}/>`;
     }
 
-    public SelectedDocs: FieldId[] = []
-    @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : 0;
-    @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : 0;
-
-    @computed private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, 0); }
-    @computed private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); }
+    private _mainCont = React.createRef<HTMLDivElement>();
     // "inherited" CollectionView API starts here...
 
+    public SelectedDocs: FieldId[] = []
     public active: () => boolean = () => CollectionView.Active(this);
 
     addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); }
@@ -40,11 +38,74 @@ export class CollectionVideoView extends React.Component<CollectionViewProps> {
     get collectionViewType(): CollectionViewType { return CollectionViewType.Freeform; }
     get subView(): any { return CollectionView.SubView(this); }
 
+    componentDidMount() {
+        this.repete();
+    }
+
+    player = (): HTMLVideoElement => {
+        return this._mainCont.current!.getElementsByTagName("video")[0];
+    }
+
+    @action
+    repete = () => {
+        if (this.player()) {
+            this.ctime = this.player().currentTime;
+            this.props.Document.SetNumber(KeyStore.CurPage, Math.round(this.ctime));
+        }
+        setTimeout(() => this.repete(), 100)
+    }
+
+
+    @observable
+    ctime: number = 0
+    @observable
+    playing: boolean = false;
+
+    @action
+    onPlayDown = () => {
+        if (this.player()) {
+            if (this.player().paused) {
+                this.player().play();
+                this.playing = true;
+            } else {
+                this.player().pause();
+                this.playing = false;
+            }
+        }
+    }
+    @action
+    onFullDown = (e: React.PointerEvent) => {
+        if (this.player()) {
+            this.player().requestFullscreen();
+            e.stopPropagation();
+            e.preventDefault();
+        }
+    }
+
+    @action
+    onResetDown = () => {
+        if (this.player()) {
+            this.player().pause();
+            this.player().currentTime = 0;
+        }
+
+    }
+
     render() {
-        return (<div className="collectionView-cont" onContextMenu={this.specificContextMenu}>
-            {/* <video controls className="videobox-cont"> */}
-            {this.subView}
-            {/* </video> */}
+        return (<div className="collectionVideoView-cont" ref={this._mainCont} onContextMenu={this.specificContextMenu}>
+            <div className="collectionVideoView-controls" >
+                {this.subView}
+                <div className="collectionVideoView-time" onPointerDown={this.onResetDown}>
+                    <span>{"" + Math.round(this.ctime)}</span>
+                    <span style={{ fontSize: 8 }}>{" " + Math.round((this.ctime - Math.trunc(this.ctime)) * 100)}</span>
+                </div>
+                <div className="collectionVideoView-play" onPointerDown={this.onPlayDown}>
+                    {this.playing ? "\"" : ">"}
+                </div>
+                <div className="collectionVideoView-full" onPointerDown={this.onFullDown}>
+                    F
+                </div>
+            </div>
         </div>)
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 17a0fbd23..bbb4a5d83 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -50,7 +50,7 @@ export class CollectionView extends React.Component<CollectionViewProps> {
 
     @action
     public static AddDocument(props: CollectionViewProps, doc: Document) {
-        doc.SetNumber(KeyStore.Page, props.Document.GetNumber(KeyStore.CurPage, 0));
+        doc.SetNumber(KeyStore.Page, props.Document.GetNumber(KeyStore.CurPage, -1));
         if (props.Document.Get(props.fieldKey) instanceof Field) {
             //TODO This won't create the field if it doesn't already exist
             const value = props.Document.GetData(props.fieldKey, ListField, new Array<Document>())
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 544af41a2..b0b5a63a4 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -86,7 +86,7 @@ export class PDFBox extends React.Component<FieldViewProps> {
     @observable private _interactive: boolean = false;
     @observable private _loaded: boolean = false;
 
-    @computed private get curPage() { return this.props.doc.GetNumber(KeyStore.CurPage, 0); }
+    @computed private get curPage() { return this.props.doc.GetNumber(KeyStore.CurPage, -1); }
 
     componentDidMount() {
         this._reactionDisposer = reaction(
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 9c60d4348..053d9dd56 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -51,7 +51,7 @@ export class VideoBox extends React.Component<FieldViewProps> {
             <div style={{ width: "100%", height: "Auto" }} >
                 <Measure onResize={this.setScaling}>
                     {({ measureRef }) =>
-                        <video controls className="videobox-cont" ref={measureRef}>
+                        <video className="videobox-cont" ref={measureRef}>
                             <source src={path} type="video/mp4" />
                             Not supported.
                         </video>
diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts
index 6481e14fe..f93a68c85 100644
--- a/src/fields/KeyStore.ts
+++ b/src/fields/KeyStore.ts
@@ -33,7 +33,6 @@ export namespace KeyStore {
     export const LinkTags = new Key("LinkTag");
     export const Thumbnail = new Key("Thumbnail");
     export const CurPage = new Key("CurPage");
-    export const CurFrame = new Key("CurFrame");
     export const NumPages = new Key("NumPages");
     export const Ink = new Key("Ink");
 }
-- 
cgit v1.2.3-70-g09d2


From f905d60fecaf7301c1ffb716529d6e5b86130798 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 14 Mar 2019 02:11:39 -0400
Subject: fixed marquee

---
 src/client/views/collections/CollectionPDFView.tsx     | 3 ++-
 src/client/views/collections/CollectionSchemaView.scss | 5 +++++
 src/client/views/collections/CollectionVideoView.tsx   | 1 +
 src/client/views/collections/CollectionView.tsx        | 5 ++---
 4 files changed, 10 insertions(+), 4 deletions(-)

(limited to 'src/client/views/collections/CollectionView.tsx')

diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx
index 91ffc9500..be3a281f2 100644
--- a/src/client/views/collections/CollectionPDFView.tsx
+++ b/src/client/views/collections/CollectionPDFView.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 { KeyStore } from "../../../fields/KeyStore";
@@ -32,6 +32,7 @@ export class CollectionPDFView extends React.Component<CollectionViewProps> {
     }
 
     // "inherited" CollectionView API starts here...
+    @observable
     public SelectedDocs: FieldId[] = []
     public active: () => boolean = () => CollectionView.Active(this);
 
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index d40e6d314..c4e6528e5 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -71,6 +71,11 @@
                 max-width: 100%;
                 height: 100%
             }
+            .videobox-cont  {
+                object-fit: contain;
+                max-width: 100%;
+                height: 100%
+            }
         }
         .rt-tr-group {
             border-width: 1;
diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx
index 058325b21..9856a1284 100644
--- a/src/client/views/collections/CollectionVideoView.tsx
+++ b/src/client/views/collections/CollectionVideoView.tsx
@@ -23,6 +23,7 @@ export class CollectionVideoView extends React.Component<CollectionViewProps> {
     private _mainCont = React.createRef<HTMLDivElement>();
     // "inherited" CollectionView API starts here...
 
+    @observable
     public SelectedDocs: FieldId[] = []
     public active: () => boolean = () => CollectionView.Active(this);
 
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index bbb4a5d83..303379fc4 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -27,15 +27,14 @@ export const COLLECTION_BORDER_WIDTH = 2;
 @observer
 export class CollectionView extends React.Component<CollectionViewProps> {
 
-    @observable
-    public SelectedDocs: FieldId[] = [];
-
     public static LayoutString(fieldKey: string = "DataKey") {
         return `<${CollectionView.name} Document={Document}
                     ScreenToLocalTransform={ScreenToLocalTransform} fieldKey={${fieldKey}} panelWidth={PanelWidth} panelHeight={PanelHeight} isSelected={isSelected} select={select} bindings={bindings}
                     isTopMost={isTopMost} SelectOnLoad={selectOnLoad} BackgroundView={BackgroundView} focus={focus}/>`;
     }
 
+    @observable
+    public SelectedDocs: FieldId[] = [];
     public active: () => boolean = () => CollectionView.Active(this);
     addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); }
     removeDocument = (doc: Document): boolean => { return CollectionView.RemoveDocument(this.props, doc); }
-- 
cgit v1.2.3-70-g09d2

