// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import ChannelStore from '../stores/channel_store.jsx'; 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.stopOnChannelChange = this.stopOnChannelChange.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 }); return null; } play() { this.setState({playing: true}); if (ChannelStore.getCurrentId() === this.props.channelId) { ChannelStore.addChangeListener(this.stopOnChannelChange); } } stop() { this.setState({playing: false}); } stopOnChannelChange() { if (ChannelStore.getCurrentId() !== this.props.channelId) { this.stop(); } } render() { let header = 'Youtube'; if (this.state.title) { header = header + ' - '; } let content; if (this.state.playing) { content = (