aboutsummaryrefslogtreecommitdiff
path: root/src/client/apis
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/apis')
-rw-r--r--src/client/apis/youtube/YoutubeBox.scss13
-rw-r--r--src/client/apis/youtube/YoutubeBox.tsx112
2 files changed, 125 insertions, 0 deletions
diff --git a/src/client/apis/youtube/YoutubeBox.scss b/src/client/apis/youtube/YoutubeBox.scss
new file mode 100644
index 000000000..e6ccfea90
--- /dev/null
+++ b/src/client/apis/youtube/YoutubeBox.scss
@@ -0,0 +1,13 @@
+ul {
+ list-style-type: none;
+}
+
+
+li {
+ margin: 4px;
+}
+
+li:hover {
+ cursor: pointer;
+ opacity: 0.8;
+} \ No newline at end of file
diff --git a/src/client/apis/youtube/YoutubeBox.tsx b/src/client/apis/youtube/YoutubeBox.tsx
new file mode 100644
index 000000000..3e7e9e06d
--- /dev/null
+++ b/src/client/apis/youtube/YoutubeBox.tsx
@@ -0,0 +1,112 @@
+import "../../views/nodes/WebBox.scss";
+import React = require("react");
+import { FieldViewProps, FieldView } from "../../views/nodes/FieldView";
+import { HtmlField } from "../../../new_fields/HtmlField";
+import { WebField } from "../../../new_fields/URLField";
+import { observer } from "mobx-react";
+import { computed, reaction, IReactionDisposer, observable, action } from 'mobx';
+import { DocumentDecorations } from "../../views/DocumentDecorations";
+import { InkingControl } from "../../views/InkingControl";
+import { Utils } from "../../../Utils";
+import { DocServer } from "../../DocServer";
+import { NumCast } from "../../../new_fields/Types";
+import "./YoutubeBox.scss";
+
+
+@observer
+export class YoutubeBox extends React.Component<FieldViewProps> {
+
+ @observable YoutubeSearchElement: HTMLInputElement | undefined;
+ @observable searchResultsFound: boolean = false;
+ @observable searchResults: any[] = [];
+ @observable videoClicked: boolean = false;
+ @observable selectedVideoUrl: string = "";
+
+ public static LayoutString() { return FieldView.LayoutString(YoutubeBox); }
+
+ componentWillMount() {
+ DocServer.getYoutubeChannels();
+ }
+
+ _ignore = 0;
+ onPreWheel = (e: React.WheelEvent) => {
+ this._ignore = e.timeStamp;
+ }
+ onPrePointer = (e: React.PointerEvent) => {
+ this._ignore = e.timeStamp;
+ }
+ onPostPointer = (e: React.PointerEvent) => {
+ if (this._ignore !== e.timeStamp) {
+ e.stopPropagation();
+ }
+ }
+ onPostWheel = (e: React.WheelEvent) => {
+ if (this._ignore !== e.timeStamp) {
+ e.stopPropagation();
+ }
+ }
+
+ onEnterKeyDown = (e: React.KeyboardEvent) => {
+ if (e.keyCode === 13) {
+ let submittedTitle = this.YoutubeSearchElement!.value;
+ this.YoutubeSearchElement!.value = "";
+ this.YoutubeSearchElement!.blur();
+ DocServer.getYoutubeVideos(submittedTitle, this.processesVideoResults);
+
+ }
+ }
+
+ @action
+ processesVideoResults = (videos: any[]) => {
+ this.searchResults = videos;
+ if (this.searchResults.length > 0) {
+ this.searchResultsFound = true;
+ this.searchResults.forEach((video) => console.log("Image Url", video.snippet));
+ if (this.videoClicked) {
+ this.videoClicked = false;
+ }
+ }
+ }
+
+ renderSearchResultsOrVideo = () => {
+ if (this.searchResultsFound) {
+ return <ul>
+ {this.searchResults.map((video) => {
+ return <li onClick={() => this.embedVideoOnClick(video.id.videoId)} key={video.id.videoId}><img src={video.snippet.thumbnails.medium.url} /> {video.snippet.title}</li>;
+ })}
+ </ul>;
+ } else if (this.videoClicked) {
+ return <iframe src={this.selectedVideoUrl} height={NumCast(this.props.Document.height) - 40} width={NumCast(this.props.Document.width)}></iframe>;
+ } else {
+ return (null);
+ }
+ }
+
+ @action
+ embedVideoOnClick = (videoId: string) => {
+ let embeddedUrl = "https://www.youtube.com/embed/" + videoId;
+ this.selectedVideoUrl = embeddedUrl;
+ this.searchResultsFound = false;
+ this.videoClicked = true;
+ }
+
+ render() {
+ let field = this.props.Document[this.props.fieldKey];
+ let content =
+ <div style={{ width: "100%", height: "100%", position: "absolute" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
+ <input type="text" placeholder="Search for a video" onKeyDown={this.onEnterKeyDown} style={{ height: 40, width: "100%", border: "1px solid black", padding: 5, textAlign: "center" }} ref={(e) => this.YoutubeSearchElement = e!} />
+ {this.renderSearchResultsOrVideo()}
+ </div>;
+
+ let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting;
+
+ let classname = "webBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !DocumentDecorations.Instance.Interacting ? "-interactive" : "");
+ return (
+ <>
+ <div className={classname} >
+ {content}
+ </div>
+ {!frozen ? (null) : <div className="webBox-overlay" onWheel={this.onPreWheel} onPointerDown={this.onPrePointer} onPointerMove={this.onPrePointer} onPointerUp={this.onPrePointer} />}
+ </>);
+ }
+} \ No newline at end of file