{"version":3,"file":"js/videoPlayer-2f9b6a50e6136b30c115.js","sources":["webpack:///webpack/bootstrap","webpack:///./app/javascript/packs/videoPlayer.js","webpack:///./app/javascript/utils/media.js"],"sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/packs-test/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./app/javascript/packs/videoPlayer.js\");\n","import {\n isMediaPlayer,\n updateProgressBar,\n getCurrentProgressInPercentage,\n getMinuteSecondsFormat,\n addMediaPlayerEvents,\n resetProgressBar,\n resetReactions,\n saveReaction,\n isAudioPlaying,\n stopAudios,\n updateTimeElapsed,\n checkPlayerPlayPauseIcon,\n updateMediaPlayerData,\n onProgressBarClick,\n videoIsPlaying,\n checkIfHasNext,\n checkIfHasPrevious,\n reactionElementAt,\n setupLikes,\n loadReactions,\n getMediaPlayerData\n} from '../utils/media';\n\nwindow.player = null;\nlet customBarTimeInterval = null;\nlet currentTime = 0;\nlet currentVideoId = null;\nlet reactionLoaded = false;\n\nwindow.getIdFromVideoLink = function(link) {\n if (link.indexOf('http') > -1) {\n const regExp = /^.*((youtu.be\\/)|(v\\/)|(\\/u\\/\\w\\/)|(embed\\/)|(watch\\?))\\??v?=?([^#&?]*).*/;\n const match = link.match(regExp);\n return (match&&match[7].length==11)? match[7] : false;\n }\n return link;\n};\n\nfunction addYoutubeIFrameAPI() {\n var tag = document.createElement('script');\n tag.src = \"https://www.youtube.com/iframe_api\";\n var firstScriptTag = document.getElementsByTagName('script')[0];\n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n}\n\nfunction setPlayerProgressAnimation() {\n const animationInSeconds = 5;\n const intervalInMilliseconds = 50;\n const width = 188.5;\n const piece = intervalInMilliseconds * animationInSeconds / width;\n const circle = document.querySelector('#random-offset');\n let index = 1;\n if (circle) {\n const firstLoadAnimation = window.setInterval(function() {\n const dashOffset = piece * index;\n circle.setAttribute('stroke-dashoffset', width - dashOffset)\n index += 1;\n if (dashOffset >= 188.5) {\n clearInterval(firstLoadAnimation);\n circle.classList.add('hidden');\n document.querySelector('.player__grid').classList.add('hidden');\n document.querySelector('.player__image').classList.add('hidden');\n if (!isAudioPlaying()) {\n player.playVideo();\n addMediaPlayerEvents('video');\n }\n }\n }, intervalInMilliseconds);\n }\n}\n\nfunction checkIfHasReaction() {\n const progress = getCurrentProgressInPercentage(currentTime);\n const element = reactionElementAt(progress);\n if (element) {\n const hearts = element.querySelector('.playthrough__reactions');\n if (hearts) {\n hearts.classList.remove('hidden');\n }\n }\n}\n\nfunction YTDurationToSeconds(duration) {\n let match = duration.match(/PT(\\d+H)?(\\d+M)?(\\d+S)?/);\n\n match = match.slice(1).map(function(x) {\n if (x != null) {\n return x.replace(/\\D/, '');\n }\n });\n\n const hours = (parseInt(match[0]) || 0);\n const minutes = (parseInt(match[1]) || 0);\n const seconds = (parseInt(match[2]) || 0);\n\n return hours * 3600 + minutes * 60 + seconds;\n}\n\nfunction getTrackListVideoDuration() {\n document.querySelectorAll('.media-row').forEach(async function(row) {\n if (row && row.dataset && row.dataset.videoLink) {\n const youtubeId = getIdFromVideoLink(row.dataset.videoLink);\n const apiKey = document.querySelector('#youtube-video-player').dataset.apiKey;\n const response = await window.fetch(`https://www.googleapis.com/youtube/v3/videos?part=snippet&id=${youtubeId}&key=${apiKey}&part=contentDetails`)\n const data = await response.json() || {};\n const { items = [] } = data;\n const item = items.length > 0 ? items[0] : {};\n const { contentDetails = {} } = item;\n const { duration } = contentDetails;\n const durationInSeconds = duration ? YTDurationToSeconds(duration) : null;\n row.querySelector('.media-row__time').innerText = getMinuteSecondsFormat(durationInSeconds);\n }\n })\n}\n\nfunction updateVideoDuration() {\n const duration = player.getDuration();\n document.querySelectorAll('.total-time').forEach(function(elem) {\n elem.innerText = getMinuteSecondsFormat(duration);\n });\n}\n\n\n\nfunction setVideoSelected(videoId) {\n videoId = videoId ? videoId : document.querySelector('#youtube-video-player').dataset.videoId;\n currentVideoId = videoId;\n const track = document.getElementById(`video-id-${videoId}`);\n if (track) track.classList.add('media-row--current');\n}\n\nfunction setTrackSelected(elem) {\n const currentRowSelected = document.querySelector('.media-row--current');\n if (currentRowSelected) {\n currentRowSelected.classList.remove('media-row--current');\n }\n elem.classList.add('media-row--current');\n\n addMediaPlayerEvents('video');\n\n getMediaPlayerData('Video', currentVideoId).then(function({ image, song, artist, artistUrl }) {\n updateMediaPlayerData({ image, artist, song, artistUrl, mediaId: currentVideoId });\n });\n\n checkIfHasNext(elem);\n checkIfHasPrevious(elem);\n}\n\nwindow.prepareForNewVideo = function(videoId) {\n const elem = document.querySelector(`#video-id-${videoId}`);\n currentVideoId = videoId;\n reactionLoaded = false;\n setTrackSelected(elem);\n resetReactions();\n resetProgressBar();\n getTrackListVideoDuration();\n $('#youtube-video-player').attr('data-video-id', videoId);\n};\n\nwindow.loadVideo = function(e) {\n e.preventDefault();\n const videoLink = e.currentTarget.dataset.videoLink;\n const videoId = e.currentTarget.dataset.videoId;\n currentVideoId = videoId;\n const youtubeId = getIdFromVideoLink(videoLink);\n player.loadVideoById(youtubeId);\n document.querySelector('#youtube-video-player')?.setAttribute('data-video-id', videoId);\n setTrackSelected(e.currentTarget);\n\n reactionLoaded = false;\n resetReactions();\n resetProgressBar();\n};\n\nfunction addTrackClickEvent() {\n document.querySelectorAll('.media-row').forEach(function(row) {\n row.addEventListener('click', loadVideo);\n })\n}\n\nfunction addLikeButtonEventListener() {\n const likeButton = document.querySelector('.video-player-like-button');\n if (!likeButton) return;\n\n likeButton.addEventListener('click', function() {\n setupLikes(currentTime, false, isMediaPlayer(likeButton));\n saveReaction(currentTime, currentVideoId, 'video');\n });\n}\n\nfunction addProgressBarClickEvent() {\n document.querySelectorAll('.playthrough__bar').forEach(function(progressBar) {\n progressBar.addEventListener('click', function(e) {\n onProgressBarClick(e, isMediaPlayer(progressBar), 'video');\n });\n });\n}\n\nfunction playNextVideo() {\n const next = document.querySelector('.media-row--current ~ a.media-row');\n if (next && next.dataset && next.dataset.videoLink) {\n const youtubeId = getIdFromVideoLink(next.dataset.videoLink);\n player.loadVideoById(youtubeId);\n\n currentVideoId = next.dataset.videoId;\n setTrackSelected(next);\n reactionLoaded = false;\n resetReactions();\n resetProgressBar();\n }\n}\n\nwindow.addNewVideo = function(props) {\n const { mediaId, height = 268, width = 435 } = props || {};\n const elementClassName = mediaId ? `youtube-video-player-${mediaId}` : 'youtube-video-player';\n let element = null;\n document.querySelectorAll(`.${elementClassName}`).forEach(function(el) {\n if (el.offsetWidth > 0 || el.closest(`.media-card-${mediaId}`).offsetWidth > 0) {\n element = el;\n }\n });\n const videoLink = element?.dataset?.videoLink;\n if (videoLink) {\n if (window.player) {\n window.player.pauseVideo();\n }\n\n const youtubeId = getIdFromVideoLink(videoLink);\n player = new YT.Player(element, {\n height,\n width,\n videoId: youtubeId,\n playerVars: {\n 'playsinline': 1,\n },\n events: {\n 'onReady': onPlayerReady,\n 'onStateChange': onPlayerStateChange\n }\n });\n }\n}\n\n/* Youtube methods */\nwindow.onYouTubeIframeAPIReady = function() {\n addNewVideo();\n};\n\nwindow.onPlayerReady = function(e) {\n updateVideoDuration();\n addLikeButtonEventListener();\n addProgressBarClickEvent();\n addTrackClickEvent();\n setVideoSelected(e.target.m.dataset?.videoId);\n getTrackListVideoDuration();\n\n const circle = document.querySelector('#random-offset');\n if (!circle) {\n window.player.playVideo();\n }\n};\n\nwindow.onPlayerStateChange = function(event) {\n clearInterval(customBarTimeInterval);\n if (event.data === YT.PlayerState.PLAYING) {\n let videoId = player.dataset ? player.dataset.videoId : currentVideoId\n if (currentVideoId !== videoId) {\n window.player.pauseVideo();\n currentVideoId = videoId;\n window.player = event.target;\n }\n reactionLoaded = false;\n loadReactions(currentVideoId, 'video', reactionLoaded);\n customBarTimeInterval = window.setInterval(function() {\n currentTime = player.getCurrentTime();\n updateProgressBar(currentTime, 'video');\n updateTimeElapsed(currentTime, 'video');\n checkIfHasReaction();\n }, 400);\n\n stopAudios();\n addMediaPlayerEvents('video');\n checkPlayerPlayPauseIcon();\n updateVideoDuration();\n getMediaPlayerData('Video', currentVideoId).then(function({ image, song, artist, artistUrl }) {\n updateMediaPlayerData({ image, artist, song, artistUrl, mediaId: currentVideoId });\n });\n }\n if (!videoIsPlaying()) {\n clearInterval(customBarTimeInterval);\n updateProgressBar(currentTime, 'video');\n updateTimeElapsed(currentTime, 'video');\n checkPlayerPlayPauseIcon();\n }\n if (event.data === YT.PlayerState.ENDED) {\n checkPlayerPlayPauseIcon();\n playNextVideo();\n }\n};\n\naddYoutubeIFrameAPI();\nsetPlayerProgressAnimation();\n","export function isMediaPlayer(elem) {\n return !!elem.closest('.player3');\n}\n\nexport function videoIsPlaying() {\n return window.player && window.player.getPlayerState &&\n !(window.player.getPlayerState() === YT.PlayerState.PAUSED ||\n window.player.getPlayerState() === YT.PlayerState.ENDED ||\n window.player.getPlayerState() === YT.PlayerState.UNSTARTED);\n}\n\nexport function currentMediaPlaying() {\n const playButton = document.querySelector('.player3__action--play');\n return playButton?.dataset?.type;\n}\n\nexport function progressBarLength(isMediaPlayer) {\n let progressBar = document.querySelector('.mini-progress-bar');\n if (isMediaPlayer) {\n progressBar = document.querySelector('.media-progress-bar');\n }\n if (!progressBar) return 0;\n return progressBar.parentNode.offsetWidth;\n}\n\nexport function getCurrentProgressInPixels(time, isMediaPlayer, type) {\n let duration = window.player && window.player.getDuration ? window.player.getDuration() : 0;\n if (type === 'audio') {\n duration = window.audio ? window.audio.duration : 0;\n }\n const width = progressBarLength(isMediaPlayer);\n return time * width / duration;\n}\n\nexport function getCurrentProgressInPercentage(time, isMediaPlayer, type) {\n return getCurrentProgressInPixels(time, isMediaPlayer, type) * 100 / progressBarLength(isMediaPlayer);\n}\n\nexport function getCurrentProgressInSeconds(time) {\n return Math.round(time);\n}\n\nexport function getCurrentProgressInSecondsFromPercentage(progress) {\n const duration = window.player && window.player.getDuration ? window.player.getDuration() : 0;\n return progress * duration / 100;\n}\n\nexport function updateProgressBar(time, type) {\n document.querySelectorAll(`.progress-bar-${type}`).forEach(function(progressBar) {\n const currentWidth = getCurrentProgressInPixels(time, isMediaPlayer(progressBar), type);\n progressBar.style.width = currentWidth + 'px';\n });\n}\n\nexport function updateTimeElapsed(time, type) {\n document.querySelectorAll(`.time-elapsed-${type}`).forEach(function(elem) {\n elem.innerText = getMinuteSecondsFormat(time);\n });\n}\n\nexport function onProgressBarClick(e, isMediaPlayer, type) {\n if (currentMediaPlaying() !== type) return;\n\n const { layerX, target } = e;\n const duration = type === 'video' ? window.player.getDuration() : window.audio.duration;\n let seconds = Math.floor(layerX * duration / progressBarLength(isMediaPlayer));\n\n if (target.className.indexOf('playthrough__likes') > -1) {\n seconds = getCurrentProgressInSecondsFromPercentage(target.dataset.max)\n }\n if (target.id === 'amount-of-likes') {\n seconds = getCurrentProgressInSecondsFromPercentage(target.parentNode.dataset.max)\n }\n if (type === 'video') {\n window.player.seekTo(seconds, true);\n } else {\n window.audio.currentTime = seconds;\n }\n\n updateProgressBar(seconds, type);\n updateTimeElapsed(seconds, type);\n}\n\nexport function getMinuteSecondsFormat(time) {\n const pad = '00';\n const minutes = Math.floor(time / 60);\n const seconds = (pad + Math.floor(time - minutes * 60).toString()).slice(-pad.length);\n return `${minutes}:${seconds}`;\n}\n\nexport function hideMediaPlayer() {\n const mediaPlayer = document.getElementById('media-player');\n mediaPlayer.style.opacity = 0;\n // Set timeout needed to not break animation\n window.setTimeout(function() {\n mediaPlayer.classList.add('hidden');\n }, 1000);\n}\n\nexport async function getMediaPlayerData(type, mediaId) {\n const token = document.querySelector('meta[name=\"csrf-token\"]').getAttribute('content');\n const response = await window.fetch(`/media/${type}/${mediaId}/data`, {\n method: 'GET',\n headers: {\n 'X-Requested-With': 'XMLHttpRequest',\n 'X-CSRF-Token': token,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n },\n credentials: 'same-origin'\n });\n const { image, song, artist, artist_url: artistUrl } = await response.json();\n return Promise.resolve({ image, song, artist, artistUrl });\n}\n\nexport function updateMediaPlayerData({ mediaId, image, song, artist, artistUrl }) {\n document.querySelector('.player3__preview').closest('a').href = artistUrl;\n document.querySelector('.player3__preview').src = image;\n // It was decided to swap artist and song positions in the media player\n document.querySelector('.player3__song').innerText = artist;\n document.querySelector('.player3__artist').innerText = song;\n document.querySelector('.player-like-button').setAttribute('data-id', mediaId);\n document.querySelector('#media-player').setAttribute('data-id', mediaId);\n}\n\nexport function resetProgressBar() {\n document.querySelectorAll('.progress-bar').forEach(function(progressBar) {\n progressBar.style.width = '0px';\n });\n}\n\nexport function reactionElementAt(progress) {\n const nearFive = Math.floor(progress / 5) * 5;\n const element = document.querySelector(`.playthrough__likes[data-max='${nearFive}']`);\n return element;\n}\n\nfunction addHoverToStandUpEvent(element) {\n element.addEventListener('mouseenter', function() {\n element.style.zIndex = '5';\n });\n\n element.addEventListener('mouseleave', function() {\n element.style.zIndex = '1';\n })\n}\n\nfunction deleteAnimationAfterFinished(parentNode) {\n const hearts = parentNode.querySelectorAll('.playthrough__reactions');\n window.setTimeout(function() {\n hearts.forEach(function(heart) {\n heart.remove();\n });\n }, 3000)\n}\n\nfunction setLikesElementHeight({ element, increment }) {\n if (increment >= 10) {\n element.style.height = '27px';\n element.style.width = '27px';\n element.style.zIndex = '2';\n }\n if (increment >= 50) {\n element.style.height = '34px';\n element.style.width = '34px';\n element.style.zIndex = '3';\n }\n if (increment >= 100) {\n element.style.height = '42px';\n element.style.width = '42px';\n element.style.zIndex = '4';\n }\n}\n\nfunction incrementProgressBarLike(progress, noShow) {\n const nearFive = Math.floor(progress / 5) * 5;\n document.querySelectorAll(`.playthrough__likes[data-max='${nearFive}']`).forEach(function(element) {\n const amountOfLikesElement = element.querySelector('#amount-of-likes');\n const increment = parseInt(amountOfLikesElement.innerText) + 1;\n amountOfLikesElement.innerText = increment;\n setLikesElementHeight({ element, increment });\n\n if (noShow) return;\n const hearts = document.querySelector('.playthrough__reactions').cloneNode(true);\n hearts.classList.remove('hidden');\n element.appendChild(hearts);\n\n deleteAnimationAfterFinished(element);\n });\n}\n\nfunction addLikeElement(progress, noShow, type) {\n const nearFive = Math.floor(progress / 5) * 5;\n const likesElement = document.querySelector('.playthrough__likes').cloneNode(true);\n likesElement.style.left = `${nearFive}%`;\n likesElement.style.height = '20px';\n likesElement.style.width = '20px';\n likesElement.style.cursor = 'pointer';\n likesElement.classList.add('likes-cloned');\n likesElement.setAttribute('data-max', nearFive);\n likesElement.querySelector('#amount-of-likes').innerText = '1';\n\n addHoverToStandUpEvent(likesElement);\n\n if (!noShow) {\n const hearts = likesElement.querySelector('.playthrough__reactions');\n hearts.classList.remove('hidden');\n deleteAnimationAfterFinished(likesElement);\n }\n\n if (type === 'audio') {\n const progressBar = document.querySelector('#media-player .playthrough__bar');\n progressBar.appendChild(likesElement.cloneNode(true));\n } else {\n document.querySelectorAll('.playthrough__bar').forEach(function(progressBar) {\n progressBar.appendChild(likesElement.cloneNode(true));\n });\n }\n}\n\nexport function setupLikes(time, noShow, isMediaPlayer, type = 'video') {\n const progress = getCurrentProgressInPercentage(time, isMediaPlayer, type);\n if (reactionElementAt(progress)) {\n incrementProgressBarLike(progress, noShow);\n } else {\n addLikeElement(progress, noShow, type);\n }\n}\n\nexport function saveReaction(time, mediaId, type) {\n const token = document.querySelector('meta[name=\"csrf-token\"]').getAttribute('content');\n const position = getCurrentProgressInSeconds(time);\n const mediaReaction = {\n position,\n amount: 1\n };\n if (type === 'video') {\n mediaReaction.video_id = mediaId;\n } else {\n mediaReaction.audio_id = mediaId;\n }\n window.fetch('/media_reactions', {\n method: 'POST',\n headers: {\n 'X-Requested-With': 'XMLHttpRequest',\n 'X-CSRF-Token': token,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n },\n body: JSON.stringify({ media_reaction: mediaReaction }),\n credentials: 'same-origin'\n });\n}\n\nexport function resetReactions() {\n document.querySelectorAll('.likes-cloned').forEach(function(like) {\n like.remove();\n });\n}\n\nexport async function loadReactions(mediaId, type, reactionLoaded) {\n if (reactionLoaded) return;\n\n resetReactions();\n const token = document.querySelector('meta[name=\"csrf-token\"]').getAttribute('content');\n const response = await window.fetch(`/media/${type}/${mediaId}/reactions`, {\n headers: {\n 'X-Requested-With': 'XMLHttpRequest',\n 'X-CSRF-Token': token,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n },\n credentials: 'same-origin'\n });\n const { reactions = [] } = await response.json();\n reactionLoaded = true;\n reactions.forEach(function(reaction = {}) {\n const time = reaction.position || 0;\n setupLikes(time, true, true, type);\n });\n}\n\nexport function pauseVideo() {\n if (window.player && window.player.pauseVideo) {\n window.player.pauseVideo();\n }\n}\n\nexport function setPlayPauseIcons(audio) {\n audio = audio || window.audio;\n const id = audio.closest('#media-player').dataset.id;\n document.querySelectorAll('.media-card').forEach(function(card) {\n if (card.offsetWidth > 0 || card.offsetHeight > 0) {\n if (card.dataset.id !== id || (card.dataset.id === id && audio.paused)) {\n card.querySelector('.media-clip__icon--play').style.display = 'block';\n card.querySelector('.media-clip__icon--pause').style.display = 'none';\n } else {\n card.querySelector('.media-clip__icon--play').style.display = 'none';\n card.querySelector('.media-clip__icon--pause').style.display = 'block';\n }\n }\n });\n}\n\nexport function isAudioPlaying() {\n const allAudios = document.querySelectorAll('audio');\n let isPlaying = false;\n for (let i = 0; i < allAudios.length; i++) {\n const audio = allAudios[i];\n if (!audio.paused) {\n isPlaying = true;\n break;\n }\n }\n return isPlaying;\n}\n\nexport function stopAudios() {\n document.querySelectorAll('audio').forEach(function(audio) {\n if (audio && !audio.paused) {\n audio.pause();\n setPlayPauseIcons(audio);\n }\n });\n}\n\nexport function playPreviousVideo() {\n const previous = document.querySelector('.media-row--current').previousElementSibling;\n if (previous) {\n previous.click();\n resetProgressBar();\n updateTimeElapsed(0, 'video');\n }\n\n checkIfHasPrevious(previous);\n checkIfHasNext(previous);\n}\n\nexport function playNextVideo() {\n const next = document.querySelector('.media-row--current ~ a.media-row');\n if (next) {\n next.click();\n resetProgressBar();\n updateTimeElapsed(0, 'video');\n }\n\n checkIfHasPrevious(next);\n checkIfHasNext(next);\n}\n\nexport function playPreviousAudio() {\n const button = window.audio.closest('.related-media__item');\n const previous = button ? button.previousElementSibling : null;\n if (previous) {\n previous.click();\n resetProgressBar();\n updateTimeElapsed(0, 'audio');\n }\n\n checkIfHasPrevious(previous);\n checkIfHasNext(previous);\n}\n\nexport function playNextAudio(e) {\n const button = window.audio.closest('.related-media__item');\n const next = button ? button.nextElementSibling : null;\n if (next) {\n next.click();\n resetProgressBar();\n updateTimeElapsed(0, 'audio');\n }\n\n checkIfHasNext(next);\n checkIfHasPrevious(next);\n}\n\nexport function checkIfHasPrevious(elem) {\n const previousButton = document.querySelector('.player3__action--backward');\n if (!previousButton) return;\n\n if (elem && elem.previousElementSibling) {\n previousButton.classList.remove('player3__action--disabled');\n } else {\n previousButton.classList.add('player3__action--disabled');\n }\n}\n\nexport function checkIfHasNext(elem) {\n const nextButton = document.querySelector('.player3__action--forward');\n if (!nextButton) return;\n\n if (elem && elem.nextElementSibling) {\n nextButton.classList.remove('player3__action--disabled');\n } else {\n nextButton.classList.add('player3__action--disabled');\n }\n}\n\nexport function checkPlayerPlayPauseIcon() {\n const button = document.querySelector('.player3__action--play');\n if (button.dataset.type === 'video') {\n if (videoIsPlaying()) {\n button.querySelector('.play-icon').classList.add('hidden');\n button.querySelector('.pause-icon').classList.remove('hidden');\n } else {\n button.querySelector('.play-icon').classList.remove('hidden');\n button.querySelector('.pause-icon').classList.add('hidden');\n }\n } else {\n if (window.audio && window.audio.paused) {\n button.querySelector('.play-icon').classList.remove('hidden');\n button.querySelector('.pause-icon').classList.add('hidden');\n } else {\n button.querySelector('.play-icon').classList.add('hidden');\n button.querySelector('.pause-icon').classList.remove('hidden');\n }\n }\n}\n\nexport function addPlayPauseButtonEvent() {\n checkPlayerPlayPauseIcon();\n const button = document.querySelector('.player3__action--play');\n button.addEventListener('click', function() {\n if (button.dataset.type === 'video') {\n if (videoIsPlaying()) {\n window.player.pauseVideo();\n } else {\n window.player.playVideo();\n }\n } else {\n if (window.audio && window.audio.paused) {\n window.audio.play();\n } else {\n window.audio.pause();\n }\n setPlayPauseIcons(window.audio);\n checkPlayerPlayPauseIcon();\n }\n });\n}\n\nfunction addForwardsEvent() {\n const button = document.querySelector('.player3__action--forward');\n button.addEventListener('click', function(e) {\n if (currentMediaPlaying() === 'video') {\n playNextVideo(e);\n } else {\n playNextAudio(e);\n }\n });\n}\n\nfunction addBackwardsEvent() {\n const button = document.querySelector('.player3__action--backward');\n button.addEventListener('click', function(e) {\n if (currentMediaPlaying() === 'video') {\n playPreviousVideo(e);\n } else {\n playPreviousAudio(e);\n }\n });\n}\n\nfunction addLikeButtonEventListener() {\n const likeButton = document.querySelector('.player-like-button')\n likeButton.addEventListener('click', function(e) {\n const type = currentMediaPlaying();\n const currentTime = type === 'audio'\n ? window.audio.currentTime\n : window.player.getCurrentTime();\n const mediaId = e.currentTarget.dataset.id;\n setupLikes(currentTime, false, isMediaPlayer(likeButton), type);\n saveReaction(currentTime, mediaId, type);\n });\n}\n\nexport function addMediaPlayerEvents(type) {\n const mediaPlayer = document.getElementById('media-player');\n if (type) {\n mediaPlayer.querySelector('.player3__action--play').setAttribute('data-type', type);\n mediaPlayer.querySelector('.player3__action--backward').setAttribute('data-type', type);\n mediaPlayer.querySelector('.player3__action--forward').setAttribute('data-type', type);\n }\n if (mediaPlayer.className.indexOf('hidden') > -1) {\n mediaPlayer.classList.remove('hidden');\n window.setTimeout(function() {\n // class has-player3 has to be added to html in order for the player to not be under the sidebar. Ask Anton if anything.\n document.getElementsByTagName('html')[0].classList.add('has-player3')\n mediaPlayer.style.opacity = 1;\n }, 200);\n\n addPlayPauseButtonEvent()\n addForwardsEvent();\n addBackwardsEvent();\n addLikeButtonEventListener();\n }\n}\n"],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;ACjFA;AAAA;AAAA;AAAA;AAAA;AADA;AAwBA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAEA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;;;;;;;;AC7SA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AADA;AACA;AACA;AAEA;AACA;AAIA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAcA;AAAA;AAdA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AATA;AAAA;AAAA;AAUA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAoBA;AAAA;AApBA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AARA;AAAA;AAAA;AASA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;;;;A","sourceRoot":""}