diff options
author | hmhealey <harrisonmhealey@gmail.com> | 2016-01-04 16:56:43 -0500 |
---|---|---|
committer | hmhealey <harrisonmhealey@gmail.com> | 2016-01-04 17:29:05 -0500 |
commit | 537b7a3b7168f4c1fa91dc679cdfe0d19c0b10ac (patch) | |
tree | b3ac0a207712e7a85e1a7cbad9ada9c12112c5ad /web/react/components/youtube_video.jsx | |
parent | 30ea2585bc5d8654a097bb8bae463c37aa597817 (diff) | |
download | chat-537b7a3b7168f4c1fa91dc679cdfe0d19c0b10ac.tar.gz chat-537b7a3b7168f4c1fa91dc679cdfe0d19c0b10ac.tar.bz2 chat-537b7a3b7168f4c1fa91dc679cdfe0d19c0b10ac.zip |
Move Youtube preview into its own file
Diffstat (limited to 'web/react/components/youtube_video.jsx')
-rw-r--r-- | web/react/components/youtube_video.jsx | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/web/react/components/youtube_video.jsx b/web/react/components/youtube_video.jsx new file mode 100644 index 000000000..e9b698e55 --- /dev/null +++ b/web/react/components/youtube_video.jsx @@ -0,0 +1,161 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +const ytRegex = /(?:http|https):\/\/(?:www\.)?(?:(?:youtube\.com\/(?:(?:v\/)|(\/u\/\w\/)|(?:(?:watch|embed\/watch)(?:\/|.*v=))|(?:embed\/)|(?:user\/[^\/]+\/u\/[0-9]\/)))|(?:youtu\.be\/))([^#\&\?]*)/; + +export default class YoutubeVideo extends React.Component { + constructor(props) { + super(props); + + this.updateStateFromProps = this.updateStateFromProps.bind(this); + this.handleReceivedMetadata = this.handleReceivedMetadata.bind(this); + + this.play = this.play.bind(this); + this.stop = this.stop.bind(this); + + this.state = { + playing: false, + title: '' + }; + } + + componentWillMount() { + this.updateStateFromProps(this.props); + } + + componentWillReceiveProps(nextProps) { + this.updateStateFromProps(nextProps); + } + + updateStateFromProps(props) { + const link = props.link; + + const match = link.trim().match(ytRegex); + if (!match || match[2].length !== 11) { + return; + } + + this.setState({ + videoId: match[2], + time: this.handleYoutubeTime(link) + }); + } + + handleYoutubeTime(link) { + const timeRegex = /[\\?&]t=([0-9hms]+)/; + + const time = link.match(timeRegex); + if (!time || !time[1]) { + return ''; + } + + const hours = time[1].match(/([0-9]+)h/); + const minutes = time[1].match(/([0-9]+)m/); + const seconds = time[1].match(/([0-9]+)s/); + + let ticks = 0; + + if (hours && hours[1]) { + ticks += parseInt(hours[1], 10) * 3600; + } + + if (minutes && minutes[1]) { + ticks += parseInt(minutes[1], 10) * 60; + } + + if (seconds && seconds[1]) { + ticks += parseInt(seconds[1], 10); + } + + return '&start=' + ticks.toString(); + } + + componentDidMount() { + if (global.window.mm_config.GoogleDeveloperKey) { + $.ajax({ + async: true, + url: 'https://www.googleapis.com/youtube/v3/videos', + type: 'GET', + data: {part: 'snippet', id: this.state.videoId, key: global.window.mm_config.GoogleDeveloperKey}, + success: this.handleReceivedMetadata + }); + } + } + + handleReceivedMetadata(data) { + if (!data.items.length || !data.items[0].snippet) { + return null; + } + var metadata = data.items[0].snippet; + this.setState({ + receivedYoutubeData: true, + title: metadata.title + }); + } + + play() { + this.setState({playing: true}); + } + + stop() { + this.setState({playing: false}); + } + + render() { + let header = 'Youtube'; + if (this.state.title) { + header = header + ' - '; + } + + let content; + if (this.state.playing) { + content = ( + <iframe + src={'https://www.youtube.com/embed/' + this.state.videoId + '?autoplay=1&autohide=1&border=0&wmode=opaque&fs=1&enablejsapi=1' + this.state.time} + width='480px' + height='360px' + type='text/html' + frameBorder='0' + allowFullScreen='allowfullscreen' + /> + ); + } else { + content = ( + <div className='embed-responsive embed-responsive-4by3 video-div__placeholder'> + <div className='video-thumbnail__container'> + <img + className='video-thumbnail' + src={'https://i.ytimg.com/vi/' + this.state.videoId + '/hqdefault.jpg'} + /> + <div className='block'> + <span className='play-button'><span/></span> + </div> + </div> + </div> + ); + } + + return ( + <div> + <h4> + <span className='video-type'>{header}</span> + <span className='video-title'><a href={this.props.link}>{this.state.title}</a></span> + </h4> + <div + className='video-div embed-responsive-item' + onClick={this.play} + > + {content} + </div> + </div> + ); + } + + static isYoutubeLink(link) { + return link.trim().match(ytRegex); + } +} + +YoutubeVideo.propTypes = { + link: React.PropTypes.string.isRequired +}; |