From b8ace05da169802bc18d138b83576dbab98053e9 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 30 Jul 2019 12:50:18 -0400
Subject: added youtube as button snapshots.   changed video default to 10.

---
 src/client/views/nodes/VideoBox.tsx | 49 +++++++++++++++++++++++++------------
 1 file changed, 34 insertions(+), 15 deletions(-)

(limited to 'src/client/views/nodes/VideoBox.tsx')

diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 34cb47b20..d2657227a 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -8,7 +8,6 @@ import { Cast, FieldValue, NumCast } from "../../../new_fields/Types";
 import { VideoField } from "../../../new_fields/URLField";
 import { RouteStore } from "../../../server/RouteStore";
 import { Utils } from "../../../Utils";
-import { DocServer } from "../../DocServer";
 import { Docs, DocUtils } from "../../documents/Documents";
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from "../ContextMenuItem";
@@ -21,6 +20,9 @@ import { pageSchema } from "./ImageBox";
 import "./VideoBox.scss";
 import { library } from "@fortawesome/fontawesome-svg-core";
 import { faVideo } from "@fortawesome/free-solid-svg-icons";
+import { CompileScript } from "../../util/Scripting";
+import { Doc } from "../../../new_fields/Doc";
+import { ScriptField } from "../../../new_fields/ScriptField";
 
 type VideoDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>;
 const VideoDocument = makeInterface(positionSchema, pageSchema);
@@ -165,21 +167,38 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD
                         this._videoRef && ctx.drawImage(this._videoRef, 0, 0, canvas.width, canvas.height);
                     }
 
-                    //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);
+                    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"
             });
-- 
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/nodes/VideoBox.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


From 58290b1134c98d96ac259f3fc6ecd2d2c98b1320 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Tue, 30 Jul 2019 22:01:02 -0400
Subject: fixed corsproxy video snapshot?

---
 src/client/views/nodes/VideoBox.tsx | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

(limited to 'src/client/views/nodes/VideoBox.tsx')

diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 1f8636826..704030d85 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -23,6 +23,7 @@ import { faVideo } from "@fortawesome/free-solid-svg-icons";
 import { CompileScript } from "../../util/Scripting";
 import { Doc } from "../../../new_fields/Doc";
 import { ScriptField } from "../../../new_fields/ScriptField";
+var path = require('path');
 
 type VideoDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>;
 const VideoDocument = makeInterface(positionSchema, pageSchema);
@@ -89,6 +90,13 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD
         this._youtubePlayer && this.props.addDocTab(this.props.Document, this.props.DataDoc, "inTab");
     }
 
+    choosePath(url: string) {
+        if (url.indexOf(window.location.origin) === -1) {
+            return Utils.CorsProxy(url);
+        }
+        return url;
+    }
+
     @action public Snapshot() {
         let width = NumCast(this.props.Document.width);
         let height = NumCast(this.props.Document.height);
@@ -127,7 +135,7 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD
             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 url = this.choosePath(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-"
-- 
cgit v1.2.3-70-g09d2

