From b285803c4e8c37302f6e02624a6127667d628305 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <mohammad_amoush@brown.edu>
Date: Tue, 25 Jun 2019 19:49:54 -0400
Subject: Youtube Api Exploration

---
 src/client/views/MainView.tsx | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 7d2aa3199..4868fa41c 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,5 +1,5 @@
 import { IconName, library } from '@fortawesome/fontawesome-svg-core';
-import { faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faTree, faUndoAlt, faBell } from '@fortawesome/free-solid-svg-icons';
+import { faFilePdf, faFilm, faFont, faGlobeAsia, faImage, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faTree, faUndoAlt, faBell, faPlay } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, configure, observable, runInAction, trace } from 'mobx';
 import { observer } from 'mobx-react';
@@ -89,6 +89,7 @@ export class MainView extends React.Component {
         library.add(faFilm);
         library.add(faMusic);
         library.add(faTree);
+        library.add(faPlay);
         this.initEventListeners();
         this.initAuthenticationRouters();
     }
@@ -226,6 +227,7 @@ export class MainView extends React.Component {
         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 youtubeurl = "https://www.youtube.com/embed/TqcApsGRzWw";
 
         let addTextNode = action(() => Docs.TextDocument({ borderRounding: -1, width: 200, height: 200, title: "a text note" }));
         let addColNode = action(() => Docs.FreeformDocument([], { width: this.pwidth * .7, height: this.pheight, title: "a freeform collection" }));
@@ -238,6 +240,7 @@ export class MainView extends React.Component {
         let addImageNode = action(() => Docs.ImageDocument(imgurl, { width: 200, title: "an image of a cat" }));
         let addWebNode = action(() => Docs.WebDocument(weburl, { width: 200, height: 200, title: "a sample web page" }));
         let addAudioNode = action(() => Docs.AudioDocument(audiourl, { width: 200, height: 200, title: "audio node" }));
+        let addYoutubeSearcher = action(() => Docs.YoutubeDocument(youtubeurl, { width: 200, height: 200, title: "youtube node" }));
 
         let btns: [React.RefObject<HTMLDivElement>, IconName, string, () => Doc][] = [
             [React.createRef<HTMLDivElement>(), "font", "Add Textbox", addTextNode],
@@ -249,6 +252,7 @@ export class MainView extends React.Component {
             [React.createRef<HTMLDivElement>(), "object-group", "Add Collection", addColNode],
             [React.createRef<HTMLDivElement>(), "tree", "Add Tree", addTreeNode],
             [React.createRef<HTMLDivElement>(), "table", "Add Schema", addSchemaNode],
+            [React.createRef<HTMLDivElement>(), "play", "Add Youtube Searcher", addYoutubeSearcher]
         ];
 
         return < div id="add-nodes-menu" >
-- 
cgit v1.2.3-70-g09d2


From 9c868077db569a606ec465557d9d693bcd3abd34 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <mohammad_amoush@brown.edu>
Date: Tue, 16 Jul 2019 19:31:40 -0400
Subject: Merge Fixed

---
 package.json                                | 2 +-
 src/client/views/InkingControl.tsx          | 4 ++--
 src/client/views/MainView.tsx               | 4 ++--
 src/client/views/nodes/FormattedTextBox.tsx | 1 -
 4 files changed, 5 insertions(+), 6 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/package.json b/package.json
index 376d3db77..28c975500 100644
--- a/package.json
+++ b/package.json
@@ -205,4 +205,4 @@
         "xoauth2": "^1.2.0",
         "youtube": "^0.1.0"
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx
index c7f7bdb66..1910e409b 100644
--- a/src/client/views/InkingControl.tsx
+++ b/src/client/views/InkingControl.tsx
@@ -1,5 +1,5 @@
 import { observable, action, computed, runInAction } from "mobx";
-import { ColorResult } from 'react-color';
+import { ColorState } from 'react-color';
 import React = require("react");
 import { observer } from "mobx-react";
 import "./InkingControl.scss";
@@ -41,7 +41,7 @@ export class InkingControl extends React.Component {
     }
 
     @undoBatch
-    switchColor = action((color: ColorResult): void => {
+    switchColor = action((color: ColorState): void => {
         this._selectedColor = color.hex + (color.rgb.a !== undefined ? this.decimalToHexString(Math.round(color.rgb.a * 255)) : "ff");
         if (InkingControl.Instance.selectedTool === InkTool.None) {
             if (MainOverlayTextBox.Instance.SetColor(color.hex)) return;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 5a2e0c6c3..18e98a5cc 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,5 +1,5 @@
 import { IconName, library } from '@fortawesome/fontawesome-svg-core';
-import { faArrowDown, faCloudUploadAlt, faArrowUp, faClone, faCheck, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faPortrait, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt, faCat } from '@fortawesome/free-solid-svg-icons';
+import { faArrowDown, faCloudUploadAlt, faArrowUp, faClone, faCheck, faPlay, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faPortrait, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt, faCat } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, configure, observable, runInAction, reaction, trace } from 'mobx';
 import { observer } from 'mobx-react';
@@ -381,7 +381,7 @@ export class MainView extends React.Component {
         let addImageNode = action(() => Docs.Create.ImageDocument(imgurl, { width: 200, title: "an image of a cat" }));
         let addImportCollectionNode = action(() => Docs.Create.DirectoryImportDocument({ title: "Directory Import", width: 400, height: 400 }));
         let youtubeurl = "https://www.youtube.com/embed/TqcApsGRzWw";
-        let addYoutubeSearcher = action(() => Docs.YoutubeDocument(youtubeurl, { width: 200, height: 200, title: "youtube node" }));
+        let addYoutubeSearcher = action(() => Docs.Create.YoutubeDocument(youtubeurl, { width: 200, height: 200, title: "youtube node" }));
 
         let btns: [React.RefObject<HTMLDivElement>, IconName, string, () => Doc][] = [
             [React.createRef<HTMLDivElement>(), "object-group", "Add Collection", addColNode],
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 45e7171d2..3e15f2ca9 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -308,7 +308,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
                 href = parent.childNodes[0].href ? parent.childNodes[0].href : parent.href;
             }
             if (href) {
-                ``
                 if (href.indexOf(DocServer.prepend("/doc/")) === 0) {
                     this._linkClicked = href.replace(DocServer.prepend("/doc/"), "").split("?")[0];
                     if (this._linkClicked) {
-- 
cgit v1.2.3-70-g09d2


From 55bc9d93a8f39dfc6781677677dd3e4c55642c15 Mon Sep 17 00:00:00 2001
From: Mohammad Amoush <mohammad_amoush@brown.edu>
Date: Thu, 18 Jul 2019 18:13:10 -0400
Subject: Small css stuff

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

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 18e98a5cc..5a1b1991e 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -381,7 +381,7 @@ export class MainView extends React.Component {
         let addImageNode = action(() => Docs.Create.ImageDocument(imgurl, { width: 200, title: "an image of a cat" }));
         let addImportCollectionNode = action(() => Docs.Create.DirectoryImportDocument({ title: "Directory Import", width: 400, height: 400 }));
         let youtubeurl = "https://www.youtube.com/embed/TqcApsGRzWw";
-        let addYoutubeSearcher = action(() => Docs.Create.YoutubeDocument(youtubeurl, { width: 200, height: 200, title: "youtube node" }));
+        let addYoutubeSearcher = action(() => Docs.Create.YoutubeDocument(youtubeurl, { width: 600, height: 600, title: "youtube search" }));
 
         let btns: [React.RefObject<HTMLDivElement>, IconName, string, () => Doc][] = [
             [React.createRef<HTMLDivElement>(), "object-group", "Add Collection", addColNode],
-- 
cgit v1.2.3-70-g09d2


From f1cb6a2212b11ba6d18dfa2e800b2c8e4ad94a88 Mon Sep 17 00:00:00 2001
From: fawn <fangrui_tong@brown.edu>
Date: Mon, 29 Jul 2019 14:28:25 -0400
Subject: made hit box on col resizer smaller and hit box on coll expander
 bigger

---
 src/client/documents/Documents.ts                  |  8 ++---
 src/client/views/MainView.tsx                      |  2 +-
 .../views/collections/CollectionSchemaCells.tsx    |  2 +-
 .../views/collections/CollectionSchemaView.scss    | 39 +++++++++++++++-------
 .../views/collections/CollectionSchemaView.tsx     |  6 ++--
 .../collections/collectionFreeForm/MarqueeView.tsx |  2 +-
 src/client/views/nodes/LinkEditor.tsx              |  2 +-
 src/client/views/nodes/LinkMenuGroup.tsx           |  2 +-
 src/new_fields/SchemaHeaderField.ts                |  4 +--
 9 files changed, 41 insertions(+), 26 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index ee1b9fd0d..01e3ced5d 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -404,7 +404,7 @@ export namespace Docs {
         }
 
         export function FreeformDocument(documents: Array<Doc>, options: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title")]), ...options, viewType: CollectionViewType.Freeform });
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Freeform });
         }
 
         export function SchemaDocument(schemaColumns: SchemaHeaderField[], documents: Array<Doc>, options: DocumentOptions) {
@@ -412,15 +412,15 @@ export namespace Docs {
         }
 
         export function TreeDocument(documents: Array<Doc>, options: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title")]), ...options, viewType: CollectionViewType.Tree });
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Tree });
         }
 
         export function StackingDocument(documents: Array<Doc>, options: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title")]), ...options, viewType: CollectionViewType.Stacking });
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Stacking });
         }
 
         export function MasonryDocument(documents: Array<Doc>, options: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title")]), ...options, viewType: CollectionViewType.Masonry });
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Masonry });
         }
 
         export function ButtonDocument(options?: DocumentOptions) {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index f5a6715e5..d4c0711a2 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -375,7 +375,7 @@ export class MainView extends React.Component {
         let imgurl = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg";
 
         // let addDockingNode = action(() => Docs.Create.StandardCollectionDockingDocument([{ doc: addColNode(), initialWidth: 200 }], { width: 200, height: 200, title: "a nested docking freeform collection" }));
-        let addSchemaNode = action(() => Docs.Create.SchemaDocument([new SchemaHeaderField("title")], [], { width: 200, height: 200, title: "a schema collection" }));
+        let addSchemaNode = action(() => Docs.Create.SchemaDocument([new SchemaHeaderField("title", "#f1efeb")], [], { width: 200, height: 200, title: "a schema collection" }));
         //let addTreeNode = action(() => Docs.TreeDocument([CurrentUserUtils.UserDocument], { width: 250, height: 400, title: "Library:" + CurrentUserUtils.email, dropAction: "alias" }));
         // let addTreeNode = action(() => Docs.TreeDocument(this._northstarSchemas, { width: 250, height: 400, title: "northstar schemas", dropAction: "copy"  }));
         let addColNode = action(() => Docs.Create.FreeformDocument([], { width: this.pwidth * .7, height: this.pheight, title: "a freeform collection" }));
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 194765880..e06a5c66b 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -108,7 +108,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                 this._document[fieldKey] = de.data.draggedDocuments[0];
             }
             else {
-                let coll = Docs.Create.SchemaDocument([new SchemaHeaderField("title")], de.data.draggedDocuments, {});
+                let coll = Docs.Create.SchemaDocument([new SchemaHeaderField("title", "f1efeb")], de.data.draggedDocuments, {});
                 this._document[fieldKey] = coll;
             }
             e.stopPropagation();
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 053d6452c..749b9a364 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -97,15 +97,6 @@
             // margin-right: -30px;
         }
 
-        .rt-resizable-header {
-            padding: 0;
-            height: 30px;
-
-            &:last-child {
-                overflow: visible;
-            }
-        }
-
         .rt-resizable-header-content {
             height: 100%;
             overflow: visible;
@@ -198,8 +189,22 @@
     }
 
     .rt-resizer {
-        width: 20px;
-        right: -10px;
+        width: 8px;
+        right: -4px;
+    }
+
+    .rt-resizable-header {
+        padding: 0;
+        height: 30px;
+    }
+
+    .rt-resizable-header:last-child {
+        overflow: visible;
+        border: 3px solid red !important;
+
+        .rt-resizer {
+            width: 5px !important;
+        }
     }
 }
 
@@ -318,7 +323,7 @@ button.add-column {
         input[type="radio"] {
             display: none;
         }
-        
+
         .columnMenu-colorPicker {
             width: 20px;
             height: 20px;
@@ -497,4 +502,14 @@ button.add-column {
 
 .collectionSchemaView-expander {
     height: 100%;
+    min-height: 30px;
+    position: relative;
+    color: gray;
+
+    svg {
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        transform: translate(-50%, -50%);
+    }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 53dd9523b..ece638ec7 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -635,15 +635,15 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         let list = Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField));
         if (list === undefined) {
             console.log("change columns new");
-            this.props.Document.schemaColumns = list = new List<SchemaHeaderField>([new SchemaHeaderField(newKey, "f1efeb")]);
+            this.props.Document.schemaColumns = list = new List<SchemaHeaderField>([new SchemaHeaderField(newKey, "#f1efeb")]);
         } else {
             console.log("change column");
             if (addNew) {
-                this.columns.push(new SchemaHeaderField(newKey, "f1efeb"));
+                this.columns.push(new SchemaHeaderField(newKey, "#f1efeb"));
             } else {
                 const index = list.map(c => c.heading).indexOf(oldKey);
                 if (index > -1) {
-                    list[index] = new SchemaHeaderField(newKey, "f1efeb");
+                    list[index] = new SchemaHeaderField(newKey, "#f1efeb");
                 }
             }
         }
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 1c767e012..7decadbe9 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -135,7 +135,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
                 doc.width = 200;
                 docList.push(doc);
             }
-            let newCol = Docs.Create.SchemaDocument([...(groupAttr ? [new SchemaHeaderField("_group")] : []), ...columns.filter(c => c).map(c => new SchemaHeaderField(c))], docList, { x: x, y: y, title: "droppedTable", width: 300, height: 100 });
+            let newCol = Docs.Create.SchemaDocument([...(groupAttr ? [new SchemaHeaderField("_group", "#f1efeb")] : []), ...columns.filter(c => c).map(c => new SchemaHeaderField(c))], docList, { x: x, y: y, title: "droppedTable", width: 300, height: 100 });
 
             this.props.addDocument(newCol, false);
         }
diff --git a/src/client/views/nodes/LinkEditor.tsx b/src/client/views/nodes/LinkEditor.tsx
index 0ea948c81..ecb3e9db4 100644
--- a/src/client/views/nodes/LinkEditor.tsx
+++ b/src/client/views/nodes/LinkEditor.tsx
@@ -290,7 +290,7 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
         let keys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
         let index = keys.indexOf("");
         if (index > -1) keys.splice(index, 1);
-        let cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c));
+        let cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c, "#f1efeb"));
         let docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType);
         let createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" }));
         let ref = React.createRef<HTMLDivElement>();
diff --git a/src/client/views/nodes/LinkMenuGroup.tsx b/src/client/views/nodes/LinkMenuGroup.tsx
index 0cb216aa6..e04044266 100644
--- a/src/client/views/nodes/LinkMenuGroup.tsx
+++ b/src/client/views/nodes/LinkMenuGroup.tsx
@@ -72,7 +72,7 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
         let keys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
         let index = keys.indexOf("");
         if (index > -1) keys.splice(index, 1);
-        let cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c));
+        let cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c, "#f1efeb"));
         let docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType);
         let createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" }));
         let ref = React.createRef<HTMLDivElement>();
diff --git a/src/new_fields/SchemaHeaderField.ts b/src/new_fields/SchemaHeaderField.ts
index d124a3907..475296d5c 100644
--- a/src/new_fields/SchemaHeaderField.ts
+++ b/src/new_fields/SchemaHeaderField.ts
@@ -48,12 +48,12 @@ export class SchemaHeaderField extends ObjectField {
     color: string;
     type: number;
 
-    constructor(heading: string = "", color?: string, type?: ColumnType) {
+    constructor(heading: string = "", color: string, type?: ColumnType) {
         console.log("CREATING SCHEMA HEADER FIELD");
         super();
 
         this.heading = heading;
-        this.color = color === "" || color === undefined ? RandomPastel() : color;
+        this.color = color === undefined ? "#000" : color;
         if (type) {
             this.type = type;
         }
-- 
cgit v1.2.3-70-g09d2


From 937af0cd2b2c01e7971c1edf120567ee15a4d5b9 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 30 Jul 2019 13:43:02 -0400
Subject: fixed snapshots for youtube videos.

---
 src/client/views/MainView.tsx                      |   3 +-
 .../views/collections/CollectionVideoView.scss     |   9 ++
 .../views/collections/CollectionVideoView.tsx      |  24 +++--
 src/client/views/nodes/VideoBox.tsx                | 101 +++++++++++----------
 4 files changed, 80 insertions(+), 57 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index ababbe949..88a636784 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,5 +1,5 @@
 import { IconName, library } from '@fortawesome/fontawesome-svg-core';
-import { faArrowDown, faCloudUploadAlt, faArrowUp, faClone, faCheck, faPlay, faCaretUp, faLongArrowAltRight, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faPortrait, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt, faCat, faBolt } from '@fortawesome/free-solid-svg-icons';
+import { faArrowDown, faCloudUploadAlt, faArrowUp, faClone, faCheck, faPlay, faPause, faCaretUp, faLongArrowAltRight, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faPortrait, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt, faCat, faBolt } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, configure, observable, runInAction, reaction, trace } from 'mobx';
 import { observer } from 'mobx-react';
@@ -126,6 +126,7 @@ export class MainView extends React.Component {
         library.add(faMusic);
         library.add(faTree);
         library.add(faPlay);
+        library.add(faPause);
         library.add(faClone);
         library.add(faCut);
         library.add(faCommentAlt);
diff --git a/src/client/views/collections/CollectionVideoView.scss b/src/client/views/collections/CollectionVideoView.scss
index 9d2c23d3e..509851ebb 100644
--- a/src/client/views/collections/CollectionVideoView.scss
+++ b/src/client/views/collections/CollectionVideoView.scss
@@ -6,6 +6,7 @@
     top: 0;
     left:0;
     z-index: -1;
+    display:inline-table;
 }
 .collectionVideoView-time{
     color : white;
@@ -15,6 +16,14 @@
     background-color: rgba(50, 50, 50, 0.2);
     transform-origin: left top;
 }
+.collectionVideoView-snapshot{
+    color : white;
+    top :25px;
+    right : 25px;
+    position: absolute;
+    background-color: rgba(50, 50, 50, 0.2);
+    transform-origin: left top;
+}
 .collectionVideoView-play {
     width: 25px;
     height: 20px;
diff --git a/src/client/views/collections/CollectionVideoView.tsx b/src/client/views/collections/CollectionVideoView.tsx
index a264cc402..5185d9d0e 100644
--- a/src/client/views/collections/CollectionVideoView.tsx
+++ b/src/client/views/collections/CollectionVideoView.tsx
@@ -9,6 +9,7 @@ import "./CollectionVideoView.scss";
 import React = require("react");
 import { InkingControl } from "../InkingControl";
 import { InkTool } from "../../../new_fields/InkField";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 
 
 @observer
@@ -21,18 +22,20 @@ export class CollectionVideoView extends React.Component<FieldViewProps> {
     private get uIButtons() {
         let scaling = Math.min(1.8, this.props.ScreenToLocalTransform().Scale);
         let curTime = NumCast(this.props.Document.curPage);
-        return ([<div className="collectionVideoView-time" key="time" onPointerDown={this.onResetDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
+        return ([<div className="collectionVideoView-time" key="time" onPointerDown={this.onResetDown} style={{ transform: `scale(${scaling})` }}>
             <span>{"" + Math.round(curTime)}</span>
             <span style={{ fontSize: 8 }}>{" " + Math.round((curTime - Math.trunc(curTime)) * 100)}</span>
         </div>,
+        <div className="collectionVideoView-snapshot" key="time" onPointerDown={this.onSnapshot} style={{ transform: `scale(${scaling})` }}>
+            <FontAwesomeIcon icon="camera" size="lg" />
+        </div>,
         VideoBox._showControls ? (null) : [
-            <div className="collectionVideoView-play" key="play" onPointerDown={this.onPlayDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
-                {this._videoBox && this._videoBox.Playing ? "\"" : ">"}
+            <div className="collectionVideoView-play" key="play" onPointerDown={this.onPlayDown} style={{ transform: `scale(${scaling})` }}>
+                <FontAwesomeIcon icon={this._videoBox && this._videoBox.Playing ? "pause" : "play"} size="lg" />
             </div>,
-            <div className="collectionVideoView-full" key="full" onPointerDown={this.onFullDown} style={{ transform: `scale(${scaling}, ${scaling})` }}>
+            <div className="collectionVideoView-full" key="full" onPointerDown={this.onFullDown} style={{ transform: `scale(${scaling})` }}>
                 F
-                </div>
-
+            </div>
         ]]);
     }
 
@@ -56,6 +59,15 @@ export class CollectionVideoView extends React.Component<FieldViewProps> {
         }
     }
 
+    @action
+    onSnapshot = (e: React.PointerEvent) => {
+        if (this._videoBox) {
+            this._videoBox.Snapshot();
+            e.stopPropagation();
+            e.preventDefault();
+        }
+    }
+
     _isclick = 0;
     @action
     onResetDown = (e: React.PointerEvent) => {
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index d2657227a..1f8636826 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -89,6 +89,56 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD
         this._youtubePlayer && this.props.addDocTab(this.props.Document, this.props.DataDoc, "inTab");
     }
 
+    @action public Snapshot() {
+        let width = NumCast(this.props.Document.width);
+        let height = NumCast(this.props.Document.height);
+        var canvas = document.createElement('canvas');
+        canvas.width = 640;
+        canvas.height = 640 * NumCast(this.props.Document.nativeHeight) / NumCast(this.props.Document.nativeWidth);
+        var ctx = canvas.getContext('2d');//draw image to canvas. scale to target dimensions
+        if (ctx) {
+            ctx.rect(0, 0, canvas.width, canvas.height);
+            ctx.fillStyle = "blue";
+            ctx.fill();
+            this._videoRef && ctx.drawImage(this._videoRef, 0, 0, canvas.width, canvas.height);
+        }
+
+        if (!this._videoRef) { // can't find a way to take snapshots of videos
+            let b = Docs.Create.ButtonDocument({
+                x: NumCast(this.props.Document.x) + width, y: NumCast(this.props.Document.y),
+                width: 150, height: 50, title: NumCast(this.props.Document.curPage).toString()
+            });
+            const script = CompileScript(`(self as any).curPage = ${NumCast(this.props.Document.curPage)}`, {
+                params: { this: Doc.name },
+                capturedVariables: { self: this.props.Document },
+                typecheck: false,
+                editable: true,
+            });
+            if (script.compiled) {
+                b.onClick = new ScriptField(script);
+                this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.addDocument && this.props.ContainingCollectionView.props.addDocument(b, false);
+            } else {
+                console.log(script.errors.map(error => error.messageText).join("\n"));
+            }
+        } else {
+            //convert to desired file format
+            var dataUrl = canvas.toDataURL('image/png'); // can also use 'image/png'
+            // if you want to preview the captured image,
+            let filename = encodeURIComponent("snapshot" + this.props.Document.title + "_" + this.props.Document.curPage).replace(/\./g, "");
+            VideoBox.convertDataUri(dataUrl, filename).then(returnedFilename => {
+                if (returnedFilename) {
+                    let url = Utils.prepend(returnedFilename);
+                    let imageSummary = Docs.Create.ImageDocument(url, {
+                        x: NumCast(this.props.Document.x) + width, y: NumCast(this.props.Document.y),
+                        width: 150, height: height / width * 150, title: "--snapshot" + NumCast(this.props.Document.curPage) + " image-"
+                    });
+                    this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.addDocument && this.props.ContainingCollectionView.props.addDocument(imageSummary, false);
+                    DocUtils.MakeLink(imageSummary, this.props.Document);
+                }
+            });
+        }
+    }
+
     @action
     updateTimecode = () => {
         this.player && (this.props.Document.curPage = this.player.currentTime);
@@ -152,56 +202,7 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD
             let subitems: ContextMenuProps[] = [];
             subitems.push({ description: "Copy path", event: () => { Utils.CopyText(url); }, icon: "expand-arrows-alt" });
             subitems.push({ description: "Toggle Show Controls", event: action(() => VideoBox._showControls = !VideoBox._showControls), icon: "expand-arrows-alt" });
-            let width = NumCast(this.props.Document.width);
-            let height = NumCast(this.props.Document.height);
-            subitems.push({
-                description: "Take Snapshot", event: async () => {
-                    var canvas = document.createElement('canvas');
-                    canvas.width = 640;
-                    canvas.height = 640 * NumCast(this.props.Document.nativeHeight) / NumCast(this.props.Document.nativeWidth);
-                    var ctx = canvas.getContext('2d');//draw image to canvas. scale to target dimensions
-                    if (ctx) {
-                        ctx.rect(0, 0, canvas.width, canvas.height);
-                        ctx.fillStyle = "blue";
-                        ctx.fill();
-                        this._videoRef && ctx.drawImage(this._videoRef, 0, 0, canvas.width, canvas.height);
-                    }
-
-                    if (!this._videoRef) { // can't find a way to take snapshots of videos
-                        let b = Docs.Create.ButtonDocument({
-                            x: NumCast(this.props.Document.x) + width, y: NumCast(this.props.Document.y), width: 150, height: 50, title: NumCast(this.props.Document.curPage).toString()
-                        });
-                        const script = CompileScript(`this.props.Document.curPage = ${NumCast(this.props.Document.curPage)}`, {
-                            params: { this: Doc.name },
-                            typecheck: false,
-                            editable: true,
-                        });
-                        if (!script.compiled) {
-                            console.log(script.errors.map(error => error.messageText).join("\n"));
-                            return;
-                        }
-                        b.onClick = new ScriptField(script);
-                        this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.addDocument && this.props.ContainingCollectionView.props.addDocument(b, false);
-                    } else {
-                        //convert to desired file format
-                        var dataUrl = canvas.toDataURL('image/png'); // can also use 'image/png'
-                        // if you want to preview the captured image,
-                        let filename = encodeURIComponent("snapshot" + this.props.Document.title + "_" + this.props.Document.curPage).replace(/\./g, "");
-                        VideoBox.convertDataUri(dataUrl, filename).then(returnedFilename => {
-                            if (returnedFilename) {
-                                let url = Utils.prepend(returnedFilename);
-                                let imageSummary = Docs.Create.ImageDocument(url, {
-                                    x: NumCast(this.props.Document.x) + width, y: NumCast(this.props.Document.y),
-                                    width: 150, height: height / width * 150, title: "--snapshot" + NumCast(this.props.Document.curPage) + " image-"
-                                });
-                                this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.addDocument && this.props.ContainingCollectionView.props.addDocument(imageSummary, false);
-                                DocUtils.MakeLink(imageSummary, this.props.Document);
-                            }
-                        });
-                    }
-                },
-                icon: "expand-arrows-alt"
-            });
+            subitems.push({ description: "Take Snapshot", event: () => this.Snapshot(), icon: "expand-arrows-alt" });
             ContextMenu.Instance.addItem({ description: "Video Funcs...", subitems: subitems, icon: "video" });
         }
     }
-- 
cgit v1.2.3-70-g09d2

