aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMohammad Amoush <mohammad_amoush@brown.edu>2019-07-22 18:47:14 -0400
committerMohammad Amoush <mohammad_amoush@brown.edu>2019-07-22 18:47:14 -0400
commit4446a3a52c4cf4b03c201ab2d6a9179647686e40 (patch)
tree960914ad762daf0f7a51f55154c2fadd48bc5d92 /src
parentde7176884493c79ba11ecd871c3b444d36165367 (diff)
Pulled Duration and ViewCount details, Need to csss duration
Diffstat (limited to 'src')
-rw-r--r--src/client/DocServer.ts4
-rw-r--r--src/client/apis/youtube/YoutubeBox.scss37
-rw-r--r--src/client/apis/youtube/YoutubeBox.tsx64
-rw-r--r--src/server/Message.ts3
-rw-r--r--src/server/index.ts2
-rw-r--r--src/server/youtubeApi/youtubeApiSample.js21
6 files changed, 125 insertions, 6 deletions
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index bc5819061..8a9abb514 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -168,6 +168,10 @@ export namespace DocServer {
Utils.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.SearchVideo, userInput: videoTitle }, callBack);
}
+ export function getYoutubeVideoDetails(videoIds: string, callBack: (videoDetails: any[]) => void) {
+ Utils.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.VideoDetails, videoIds: videoIds }, callBack);
+ }
+
/**
* Given a list of Doc GUIDs, this utility function will asynchronously attempt to each id's associated
diff --git a/src/client/apis/youtube/YoutubeBox.scss b/src/client/apis/youtube/YoutubeBox.scss
index 5b539b463..00979f945 100644
--- a/src/client/apis/youtube/YoutubeBox.scss
+++ b/src/client/apis/youtube/YoutubeBox.scss
@@ -19,6 +19,27 @@ li:hover {
display: inline-flex;
height: 175px;
+ .video_duration {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ background: transparent;
+ display: inline-block;
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ margin: 4px;
+ color: #FFFFFF;
+ background-color: rgba(0, 0, 0, 0.80);
+ padding: 2px 4px;
+ border-radius: 2px;
+ letter-spacing: .5px;
+ font-size: 1.2rem;
+ font-weight: 500;
+ line-height: 1.2rem;
+
+ }
+
.textual_info {
font-family: Arial, Helvetica, sans-serif;
@@ -80,6 +101,22 @@ li:hover {
font-weight: 400;
text-transform: none;
}
+
+ .viewCount {
+
+ margin-left: 8px;
+ padding: 0;
+ border: 0;
+ background: transparent;
+ color: #606060;
+ max-width: 100%;
+ line-height: 1.8rem;
+ max-height: 3.6rem;
+ overflow: hidden;
+ font-size: 1.3rem;
+ font-weight: 400;
+ text-transform: none;
+ }
diff --git a/src/client/apis/youtube/YoutubeBox.tsx b/src/client/apis/youtube/YoutubeBox.tsx
index 7ac8d06f6..824a0251d 100644
--- a/src/client/apis/youtube/YoutubeBox.tsx
+++ b/src/client/apis/youtube/YoutubeBox.tsx
@@ -26,12 +26,15 @@ export class YoutubeBox extends React.Component<FieldViewProps> {
@observable videoClicked: boolean = false;
@observable selectedVideoUrl: string = "";
@observable lisOfBackUp: JSX.Element[] = [];
+ @observable videoIds: string | undefined;
+ @observable videoDetails: any[] = [];
public static LayoutString() { return FieldView.LayoutString(YoutubeBox); }
async componentWillMount() {
//DocServer.getYoutubeChannels();
+ //DocServer.getYoutubeVideoDetails("Ks-_Mh1QhMc, 1NmvhSmN2uM", (results: any[]) => console.log("Details results: ", results));
let castedBackUpDocs = Cast(this.props.Document.cachedSearch, listSpec(Doc));
if (!castedBackUpDocs) {
this.props.Document.cachedSearch = castedBackUpDocs = new List<Doc>();
@@ -95,6 +98,15 @@ export class YoutubeBox extends React.Component<FieldViewProps> {
this.searchResults = videos;
if (this.searchResults.length > 0) {
this.searchResultsFound = true;
+ this.videoIds = "";
+ videos.forEach((video) => {
+ if (this.videoIds === "") {
+ this.videoIds = video.id.videoId;
+ } else {
+ this.videoIds = this.videoIds! + ", " + video.id.videoId;
+ }
+ });
+ DocServer.getYoutubeVideoDetails(this.videoIds, this.processVideoDetails);
this.backUpSearchResults(videos);
if (this.videoClicked) {
this.videoClicked = false;
@@ -102,6 +114,12 @@ export class YoutubeBox extends React.Component<FieldViewProps> {
}
}
+ @action
+ processVideoDetails = (videoDetails: any[]) => {
+ this.videoDetails = videoDetails;
+ console.log("Detail Res: ", this.videoDetails);
+ }
+
backUpSearchResults = (videos: any[]) => {
let newCachedList = new List<Doc>();
this.props.Document.cachedSearch = newCachedList;
@@ -190,28 +208,64 @@ export class YoutubeBox extends React.Component<FieldViewProps> {
}
}
+ convertIsoTimeToDuration = (isoDur: string) => {
+
+ let convertedTime = isoDur.replace(/D|H|M/g, ":").replace(/P|T|S/g, "").split(":");
+
+ if (1 === convertedTime.length) {
+ 2 !== convertedTime[0].length && (convertedTime[0] = "0" + convertedTime[0]), convertedTime[0] = "0:" + convertedTime[0];
+ } else {
+ for (var r = 1, l = convertedTime.length - 1; l >= r; r++) {
+ 2 !== convertedTime[r].length && (convertedTime[r] = "0" + convertedTime[r]);
+ }
+ }
+
+ return convertedTime.join(":");
+ }
+
+ abbreviateViewCount = (viewCount: number) => {
+ if (viewCount < 1000) {
+ return viewCount.toString();
+ } else if (viewCount >= 1000 && viewCount < 1000000) {
+ return (Math.trunc(viewCount / 1000)) + "K";
+ } else if (viewCount >= 1000000 && viewCount < 1000000000) {
+ return (Math.trunc(viewCount / 1000000)) + "M";
+ } else if (viewCount >= 1000000000) {
+ return (Math.trunc(viewCount / 1000000000)) + "B";
+ }
+ }
+
renderSearchResultsOrVideo = () => {
if (this.searchResultsFound) {
if (this.searchResults.length !== 0) {
return <ul>
- {this.searchResults.map((video) => {
+ {this.searchResults.map((video, index) => {
let filteredTitle = this.filterYoutubeTitleResult(video.snippet.title);
let channelTitle = video.snippet.channelTitle;
let videoDescription = video.snippet.description;
let pusblishDate = this.roundPublishTime2(video.snippet.publishedAt);
- // let duration = video.contentDetails.duration;
- //let viewCount = video.statistics.viewCount;
+ let duration;
+ let viewCount;
+ if (this.videoDetails.length !== 0) {
+ duration = this.convertIsoTimeToDuration(this.videoDetails[index].contentDetails.duration);
+ viewCount = this.abbreviateViewCount(this.videoDetails[index].statistics.viewCount);
+ }
//this.roundPublishTime(pusblishDate);
//this.roundPublishTime2(video.snippet.publishedAt);
+
return <li onClick={() => this.embedVideoOnClick(video.id.videoId, filteredTitle)} key={Utils.GenerateGuid()}>
<div className="search_wrapper">
- <img src={video.snippet.thumbnails.medium.url} />
+ <div style={{ backgroundColor: "yellow" }}>
+ <img src={video.snippet.thumbnails.medium.url} />
+ <span className="video_duration">{duration}</span>
+ </div>
<div className="textual_info">
<span className="videoTitle">{filteredTitle}</span>
<span className="channelName">{channelTitle}</span>
+ <span className="viewCount">{viewCount}</span>
<span className="publish_time">{pusblishDate}</span>
- {/* <h6 className="viewCount">{viewCount}</h6> */}
<p className="video_description">{videoDescription}</p>
+
</div>
</div>
</li>;
diff --git a/src/server/Message.ts b/src/server/Message.ts
index 1e29aef0b..aaee143e8 100644
--- a/src/server/Message.ts
+++ b/src/server/Message.ts
@@ -25,12 +25,13 @@ export interface Transferable {
}
export enum YoutubeQueryTypes {
- Channels, SearchVideo
+ Channels, SearchVideo, VideoDetails
}
export interface YoutubeQueryInput {
readonly type: YoutubeQueryTypes;
readonly userInput?: string;
+ readonly videoIds?: string;
}
export interface Reference {
diff --git a/src/server/index.ts b/src/server/index.ts
index 60e34de8c..dfbc1a468 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -537,6 +537,8 @@ function HandleYoutubeQuery([query, callback]: [YoutubeQueryInput, (result?: any
break;
case YoutubeQueryType.SearchVideo:
YoutubeApi.authorizedGetVideos(youtubeApiKey, query.userInput, callback);
+ case YoutubeQueryType.VideoDetails:
+ YoutubeApi.authorizedGetVideoDetails(youtubeApiKey, query.videoIds, callback);
}
}
diff --git a/src/server/youtubeApi/youtubeApiSample.js b/src/server/youtubeApi/youtubeApiSample.js
index f875812d5..cf41a33e7 100644
--- a/src/server/youtubeApi/youtubeApiSample.js
+++ b/src/server/youtubeApi/youtubeApiSample.js
@@ -33,6 +33,10 @@ module.exports.authorizedGetVideos = (apiKey, userInput, callBack) => {
authorize(JSON.parse(apiKey), getSampleVideos, { userInput: userInput, callBack: callBack });
}
+module.exports.authorizedGetVideoDetails = (apiKey, videoIds, callBack) => {
+ authorize(JSON.parse(apiKey), getVideoDetails, { videoIds: videoIds, callBack: callBack });
+}
+
/**
* Create an OAuth2 client with the given credentials, and then execute the
@@ -156,4 +160,21 @@ function getSampleVideos(auth, args) {
console.log('Videos found: ' + videos[0].id.videoId, " ", unescape(videos[0].snippet.title));
args.callBack(videos);
});
+}
+
+function getVideoDetails(auth, args) {
+ let service = google.youtube('v3');
+ service.videos.list({
+ auth: auth,
+ part: 'contentDetails, statistics',
+ id: args.videoIds
+ }, function (err, response) {
+ if (err) {
+ console.log('The API returned an error: ' + err);
+ return;
+ }
+ let videoDetails = response.data.items;
+ console.log('Video Details founds: ', videoDetails);
+ args.callBack(videoDetails);
+ });
} \ No newline at end of file