import EmbedPlayer from './classes/EmbedPlayer';
import StickyVideo from './classes/StickyVideo';
import Messenger from './Messenger';
/**
* Video playlist functionality.
*
* @class VideoPlaylist
* @prop {object} states - Set of classes that serve as flags for playlist states.
* @prop {object} selectors - Set of selectors that can be used to select playlist features.
*/
const VideoPlaylist = {
states: {
playing: 'c-posts__item--playing',
},
selectors: {
main: '.l-playlist',
mainHeadline: '.l-playlist__main .l-playlist__headline',
itemLink: '.l-playlist__link',
orderedItem: '[data-playlist-index]',
player: '.c-video',
},
/**
* Initializes video playlists.
* Listens for playlist clicks to initiate video player.
*
* @method init
*/
init() {
const $targets = document.querySelectorAll( this.selectors.main );
[].forEach.call( $targets, ( $target ) => {
const $links = $target.querySelectorAll( this.selectors.itemLink );
[].forEach.call( $links, ( $link ) => {
$link.addEventListener( 'click', evt => this.handleItemClick( evt, $target, $link ) );
});
});
Messenger.registerReceiver( 'gnca_video', this );
},
/**
* Playlist item click handler. Loads selected video into player if it is not there already.
* Removes selected video from the playlist.
*
* @method handleItemClick
* @param {event} event - click event.
* @param {HTMLElement} $playlist - DOM element of the playlist.
* @param {object} data - selected video data.
*/
handleItemClick( event, $playlist, $link ) {
event.preventDefault();
const data = $link.dataset;
const $player = $playlist.querySelector( this.selectors.player );
if ( data.videoCurrent ) {
// Video player title clicked, trigger playback
if ( 'true' !== $player.dataset.displayinlineInit ) {
this.startVideo( $player );
}
} else {
// Playlist item clicked, swap out video and trigger playback
data.headline = $link.getAttribute( 'title' );
this.swapVideo( $player, data );
this.updatePlaylist( $playlist, data.videoId );
}
},
/**
* Swap out current playlist video with a new video and restart player.
*
* @method swapVideo
* @param {HTMLElement} $player - DOM element of the player.
* @param {object} data - selected video data.
*/
swapVideo( $player, data ) {
let embedPlayer = false;
if ( 'true' === $player.dataset.displayinlineInit ) {
embedPlayer = EmbedPlayer.getPlayer( data.videoPlayerId );
if ( embedPlayer ) {
const $video = StickyVideo.getVideo( data.videoPlayerId );
StickyVideo.detachCurrentVideo();
embedPlayer.reset( $video );
}
}
/* eslint-disable no-param-reassign */
$player.dataset.displayinlineInit = '';
$player.dataset.displayinline = data.embedUrl;
$player.dataset.displayinlineVideoId = data.videoId;
/* eslint-enable no-param-reassign */
this.startVideo( $player );
},
/**
* Start video
*
* @method startVideo
* @param {HTMLElement} $player - DOM element of the player.
*/
startVideo( $player ) {
const embedPlayer = new EmbedPlayer( $player );
embedPlayer.start();
},
/**
* Set playing state for selected playlist item.
* Reorder playlist so that current item sits at the top,
* or below a live stream video if one exists.
*
* @method updatePlaylist
* @param {HTMLElement} $playlist - DOM element of the playlist.
* @param {string} videoId - selected video ID
*/
updatePlaylist( $playlist, videoId ) {
const $currentItem = $playlist.querySelector( `.${this.states.playing}` );
if ( $currentItem ) {
// Now playing state already set, bail.
if ( $currentItem.querySelector( this.selectors.itemLink ).dataset.videoId === videoId ) {
return;
}
$currentItem.classList.remove( this.states.playing );
}
const $selectedLink = $playlist.querySelector( `[data-video-id="${videoId}"]` );
if ( $selectedLink ) {
const $selectedItem = $selectedLink.parentNode;
$selectedItem.classList.add( this.states.playing );
}
},
/**
* Checks to see if play event has fired for current active carousel video.
* If so, grabs current playlist index and passes along to update now playing flag.
*
* @method receiveMessage
* @param {object} data - postMessage data object.
*/
receiveMessage( data ) {
if ( data.status && data.iframeId && 'undefined' !== typeof data.playlistIndex ) {
if ( 'playlistItem' === data.status ) {
const { iframeId: playerId } = data;
let { videoPostId } = data;
const $playlist = document.querySelector( `#${this.getId( playerId )}` );
if ( $playlist ) {
// No post ID sent via window postMessage, grap ID from player
// grap ID from the player
if ( ! videoPostId ) {
const $player = $playlist.querySelector( this.selectors.player );
videoPostId = $player.dataset.displayinlineVideoId;
}
this.updatePlaylist( $playlist, videoPostId );
}
}
}
},
/**
* Get video playlist id
*
* @static
* @method getId
* @param {sting} playerId
* @return {string} The corresponding ID for that video playlist.
*/
getId( playerId ) {
return `${playerId}-playlist`;
},
};
export default VideoPlaylist;