var SITE_URL = 'www.yvmtrainer.com'; var FULL_URL = 'https://www.yvmtrainer.com'; var resolutions = [ { label: 'HD', id: 1 }, { label: '2k', id: 2 }, { label: '4k (1920p)', id: 3 }, { label: '4k (2048p)', id: 4 } ]; var PlayerInstance; var logId = 0; var checkinNavInit = false; var topMenu; var topMenuHeight; var scrollItems; function isIOS() { return [ 'iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod' ].includes(navigator.platform) // iPad on iOS 13 detection || (navigator.userAgent.includes("Mac") && "ontouchend" in document) } function isIPhone() { return [ 'iPhone Simulator', 'iPhone' ].includes(navigator.platform); } function isAndroid() { return navigator.userAgent.includes("Android"); } function goFullscreen(el) { if (el.requestFullscreen) { el.requestFullscreen(); } else if (el.mozRequestFullScreen) { el.mozRequestFullScreen(); } else if (el.webkitRequestFullScreen) { el.webkitRequestFullScreen(); } } function correctAudioPosition(t) { var aud = document.getElementById('audioTrack'); if(aud) { aud.currentTime = t; debugLog('Correct audio position: ' + t); } } function switchPlayer() { var aud = document.getElementById('audioTrack'); if(aud) { aud.pause(); debugLog('> Trigger audio pause (switchPlayer)', 'trigger'); } var wrap = document.getElementById('plyr_video-wrapper'); var t = 0; if(PlayerInstance) { t = PlayerInstance.getCurrentTime(); PlayerInstance.stop(); } wrap.innerHTML = ''; var use360 = true; if(wrap.getAttribute('data-mode') == '360') { use360 = false; } if(use360) { yvmtPlayerState('360', '360'); deviceMotionPermission(); } else { yvmtPlayerState('360', 'pan'); } if(use360 && isIPhone()) { $('#videoPlayer [data-plyr="fullscreen"]').css('display', 'none'); } else { $('#videoPlayer [data-plyr="fullscreen"]').css('display', ''); } // Hide levels until we know they are available $('#videoPlayer .plyr_menu').css('display', 'none'); if(use360) { var video = $('#videoPlayer').attr('data-video-360'); } else { var video = $('#videoPlayer').attr('data-video-pan'); } $('#videoPlayer').attr('data-resume-play', t); playClappRVideo(use360, video); } function deviceMotionPermission() { if(typeof DeviceMotionEvent != 'undefined') { if (typeof DeviceMotionEvent.requestPermission === 'function') { DeviceMotionEvent.requestPermission() .then(permissionState => { if (permissionState === 'granted') { // DeviceMotionEvent.requestPermission() has been granted } }) .catch(console.error); } } } function playHeadsetVideo(video) { try { var wrap = document.getElementById('plyr_video-wrapper'); wrap.innerHTML = ''; var vid = document.createElement('VIDEO'); vid.src = video; vid.controls = false; vid.style.width = '100%'; vid.id = 'vidEl'; addMainPlayerMediaEvents(vid, 'video'); wrap.appendChild(vid); /* if(autoPlay) { var playPromise = vid.play(); if (playPromise !== undefined) { playPromise.then(function() { goFullscreen(vid); }).catch(function(error) { }); } } */ updatePlayerQualityLevels(resolutions); } catch(error) { logit('ERROR [playHeadsetVideo]: ' + error); } } function addMainPlayerMediaEvents(el, type) { el.addEventListener('timeupdate', function() { yvmtPlayerEvent(type, 'time', { time : this.currentTime, duration: this.duration } ); if(type == 'video') { if(this.hasAttribute('data-buffering')) { if(! this.paused) { if(this.readyState == this.HAVE_ENOUGH_DATA) { this.removeAttribute('data-buffering') yvmtPlayerEvent(type, 'play'); // also correct audio position correctAudioPosition(this.currentTime); debugLog('timeupdate: good to go!'); } else { debugLog('timeupdate: not enough data: ' + this.readyState + ' != ' + this.HAVE_ENOUGH_DATA); } } else { //logit('timeupdate: paused'); } } else { //logit('timeupdate: not buffering [' + this.readyState + ']'); } } } ); el.addEventListener('volumechange', function() { yvmtPlayerEvent(type, 'volumechange', this.volume); } ); el.addEventListener('ended', function() { yvmtPlayerEvent(type, 'ended'); } ); el.addEventListener('play', function() { yvmtPlayerEvent(type, 'play'); } ); el.addEventListener('playing', function() { yvmtPlayerEvent(type, 'playing'); } ); el.addEventListener('pause', function() { yvmtPlayerEvent(type, 'pause'); } ); el.addEventListener('loadedmetadata', function() { if(this.hasAttribute('data-reset-time')) { debugLog('RESET TIME: ' + this.getAttribute('data-reset-time')); this.currentTime = parseFloat(this.getAttribute('data-reset-time')); this.removeAttribute('data-reset-time') } } ); el.addEventListener('canplay', function() { yvmtPlayerEvent(type, 'canplay'); } ); el.addEventListener('canplaythrough', function() { debugLog('CAN PLAY THROUGH'); } ); el.addEventListener('seeked', function() { yvmtPlayerEvent(type, 'seek', { time : this.currentTime, duration: this.duration } ); } ); el.addEventListener('seeking', function() { logit('start seeking'); } ); el.addEventListener('stalled', function() { logit('stalled'); } ); el.addEventListener('waiting', function() { setMediaStreamBuffering(type); } ); if(type == 'video') { el.addEventListener('resize', function() { buildQualitySelector(this.videoWidth, this.videoHeight); } ); } } function buildQualitySelector(w, h) { /* var infoDiv = document.getElementById('infoDiv'); if(infoDiv) { infoDiv.style.display = 'block'; var wrap = document.getElementById('playerWrap'); var select = document.getElementById('qualitySelector'); var active = 'auto'; if(wrap.hasAttribute('data-quality')) { active = wrap.getAttribute('data-quality'); } if(active == 'auto') { if(resolutions[w]) { select.options[0].innerHTML = 'auto: ' + resolutions[w].label; } else { select.options[0].innerHTML = 'auto'; } } } */ } function logit(message, color) { console.log(message); var wrap = document.getElementById('playerLog'); if(wrap) { var lastLog = document.getElementById('log-' + logId); // Same message if(lastLog && lastLog.getAttribute('data-message') == message) { var counter = 1; if(lastLog.hasAttribute('data-counter')) { counter = parseInt(lastLog.getAttribute('data-counter')) + 1; } lastLog.setAttribute('data-counter', counter); lastLog.innerHTML = message + ' (' + counter + 'x)'; } else { logId++; wrap.innerHTML = '
' + message + '
' + wrap.innerHTML; document.getElementById('log-' + logId).setAttribute('data-message', message); if(color) { document.getElementById('log-' + logId).style.color = color; } } } } function lockQuality(quality) { var vid = document.getElementById('vidEl'); vid.setAttribute('data-reset-time', vid.currentTime); logit('TIME: ' + vid.currentTime); if(! vid.paused) { $('#videoPlayer').attr('data-resume-play', vid.currentTime); } vid.pause(); var videoURL = $('#videoPlayer').attr('data-video-360'); if(quality >= 1) { videoURL = videoURL.replace('pl-360-hlv3', 'hls-360-' + quality + '-'); } vid.src = videoURL; vid.load(); yvmtPlayerEvent('video', 'level', quality); } function playClappRVideo(use360, video) { var wrap = document.getElementById('plyr_video-wrapper'); if(use360) { wrap.setAttribute('data-mode', '360'); } else { wrap.setAttribute('data-mode', 'pan'); } wrap.innerHTML = '
'; var clappRParams = { source: video, parentId: '#player', autoPlay: false, height: '100%', width: '100%', chromeless: true, events: { onTimeUpdate: function (data){ yvmtPlayerEvent('video', 'time', { time : data.current, duration: data.total } ); } } }; clappRParams.plugins = { 'core': [LevelSelector] }; clappRParams.levelSelectorConfig = { labelCallback: function(playbackLevel) { return playbackLevel.level.width + 'x' + playbackLevel.level.height; } }; if(use360) { clappRParams.plugins.container = [Video360]; } PlayerInstance = new Clappr.Player(clappRParams); PlayerInstance.core.activePlayback.on(Clappr.Events.PLAYBACK_LEVELS_AVAILABLE, function(levels) { updatePlayerQualityLevels(levels); }); PlayerInstance.core.activePlayback.on(Clappr.Events.PLAYBACK_LEVEL_SWITCH_START, function(level) { // console.log('NEW LEVEL'); // console.log(PlayerInstance.core.activePlayback.currentLevel); yvmtPlayerEvent('video', 'level', PlayerInstance.core.activePlayback.currentLevel); }); PlayerInstance.core.activePlayback.on(Clappr.Events.PLAYBACK_ENDED, function() { yvmtPlayerEvent('video', 'ended'); }); PlayerInstance.listenTo(PlayerInstance, Clappr.Events.PLAYER_PLAY, function() { yvmtPlayerEvent('video', 'play'); } ); PlayerInstance.listenTo(PlayerInstance, Clappr.Events.PLAYER_PAUSE, function() { yvmtPlayerEvent('video', 'pause'); } ); PlayerInstance.listenTo(PlayerInstance, Clappr.Events.PLAYER_SEEK, function(time) { yvmtPlayerEvent('video', 'seek', { time : time, duration: this.getDuration() }); } ); if(PlayerInstance.isReady) { yvmtPlayerEvent('video', 'canplay'); } else { PlayerInstance.listenTo(PlayerInstance, Clappr.Events.PLAYER_READY, function() { yvmtPlayerEvent('video', 'canplay'); } ); } PlayerInstance.listenTo(PlayerInstance, Clappr.Events.PLAYER_VOLUMEUPDATE, function(volume) { yvmtPlayerEvent('video', 'volumechange', volume / 100); } ); PlayerInstance.listenTo(PlayerInstance.core.getCurrentContainer(), Clappr.Events.CONTAINER_STATE_BUFFERING, function() { yvmtPlayerEvent('video', 'pause') } ); PlayerInstance.listenTo(PlayerInstance.core.getCurrentContainer(), Clappr.Events.CONTAINER_STATE_BUFFERFULL, function() { if(PlayerInstance.isPlaying()) { yvmtPlayerEvent('video', 'play'); } } ); $('#switchPlayerBtn').css('display', 'inline'); } function submitModalEmotion(el) { var emotionId = el.getAttribute('data-uid'); $('#videoPlayer').attr('data-emotion', emotionId); trackVideoView(emotionId); $(".pre-emotion-modal").modal('hide'); $(".pre-emotion-modal").attr('data-emotion', emotionId); yvmtPlayerTriggerEvent('play'); } function yvmtPlayerState(state, value) { if(state == 'play') { if($('#videoPlayer').attr('data-view-id') == 'pending') { // $('#videoPlayer').attr('data-view-id', 'loading'); // trackVideoView(); $('#videoPlayer').attr('data-view-id', 'emotion'); yvmtPlayerTriggerEvent('pause'); $(".pre-emotion-modal").modal(); } $('#videoPlayer [data-plyr="play"]').attr('data-state', value); if(value == 'playing') { $('#videoPlayer .plyr_controls_item .icofont-play-alt-2').removeClass('not-pressed'); $('#videoPlayer .plyr_controls_item .icofont-play-alt-2').addClass('pressed'); $('#videoPlayer .plyr_controls_item .icofont-ui-pause').addClass('not-pressed'); $('#videoPlayer .plyr_controls_item .icofont-ui-pause').removeClass('pressed'); } else { $('#videoPlayer .plyr_controls_item .icofont-play-alt-2').addClass('not-pressed'); $('#videoPlayer .plyr_controls_item .icofont-play-alt-2').removeClass('pressed'); $('#videoPlayer .plyr_controls_item .icofont-ui-pause').removeClass('not-pressed'); $('#videoPlayer .plyr_controls_item .icofont-ui-pause').addClass('pressed'); } } if(state == '360') { if(value == 'pan') { $('#videoPlayer [data-plyr="360"] .360-on').removeClass('not-pressed'); $('#videoPlayer [data-plyr="360"] .360-on').addClass('pressed'); $('#videoPlayer [data-plyr="360"] .360-off').addClass('not-pressed'); $('#videoPlayer [data-plyr="360"] .360-off').removeClass('pressed'); } else { $('#videoPlayer [data-plyr="360"] .360-on').addClass('not-pressed'); $('#videoPlayer [data-plyr="360"] .360-on').removeClass('pressed'); $('#videoPlayer [data-plyr="360"] .360-off').removeClass('not-pressed'); $('#videoPlayer [data-plyr="360"] .360-off').addClass('pressed'); } } if(state == 'mute') { $('#videoPlayer [data-plyr="mute"]').attr('data-state', value); if(value == 'muted') { $('#videoPlayer .plyr_volume .plyr_control i.icofont-ui-mute').addClass('not-pressed'); $('#videoPlayer .plyr_volume .plyr_control i.icofont-ui-mute').removeClass('pressed'); $('#videoPlayer .plyr_volume .plyr_control i.icofont-ui-volume').removeClass('not-pressed'); $('#videoPlayer .plyr_volume .plyr_control i.icofont-ui-volume').addClass('pressed'); } else { $('#videoPlayer .plyr_volume .plyr_control i.icofont-ui-mute').removeClass('not-pressed'); $('#videoPlayer .plyr_volume .plyr_control i.icofont-ui-mute').addClass('pressed'); $('#videoPlayer .plyr_volume .plyr_control i.icofont-ui-volume').addClass('not-pressed'); $('#videoPlayer .plyr_volume .plyr_control i.icofont-ui-volume').removeClass('pressed'); } } if(state == 'favourite') { $('#videoPlayer [data-plyr="favourite"]').attr('data-state', value); if(value == 'favourite') { $('#videoPlayer [data-plyr="favourite"] .icofont-heart').css('color', 'red'); } else { $('#videoPlayer [data-plyr="favourite"] .icofont-heart').css('color', ''); } } } function storeWatchTime(time, duration) { var watched = parseFloat($('#videoPlayer').attr('data-watched')); if(! watched) { watched = 0; } // Store every 5 seconds if(time > (watched + 5)) { var viewId = $('#videoPlayer').attr('data-view-id'); if(viewId !== 'pending') { if($('#videoPlayer').attr('data-store-watchtime') !== 'storing') { $('#videoPlayer').attr('data-store-watchtime', 'storing'); var percentage = Math.round(time / duration * 100); var url = FULL_URL + '/player/watchTime?v=' + viewId + '&p=' + percentage; ajaxRequest(url, function (myObject) { $('#videoPlayer').removeAttr('data-store-watchtime'); $('#videoPlayer').attr('data-watched', time); } ); } } } } function checkAutoPlay() { // Are we waiting for autoplay? if($('#videoPlayer').attr('data-autoplay') == 'true') { // Still waiting for audio? if($('#videoPlayer').attr('data-wait-audio') == 'true') { debugLog('AUTOPLAY DELAY: waiting for audio'); return false; } // Still waiting for video? if($('#videoPlayer').attr('data-wait-video') == 'true') { debugLog('AUTOPLAY DELAY: waiting for video'); return false; } debugLog('READY TO PLAY: VIDEO AND AUDIO READY TO PLAY'); $('#videoPlayer').removeAttr('data-autoplay'); $('#videoPlayer').attr('data-autoplay-started', 'true'); // All ready to play! yvmtPlayerTriggerEvent('play'); console.log('PLAY TRIGGERED BY AUTOPLAY'); } } function debugLog(msg, type) { if($('#debugMode').length > 0) { var currentdate = new Date(); div = document.createElement('DIV'); div.innerHTML = currentdate.getHours() + ':' + currentdate.getMinutes() + ':' + currentdate.getSeconds() + ' ' + msg; if(type) { if(type == 'event') { div.style.color = 'blue'; } if(type == 'trigger') { div.style.color = 'green'; } } $('#debugMode').append(div); } } function yvmtPlayerEvent(type, event, data) { console.log('EVENT: ' + type + ' - ' + event); // Ready to play media file if(event == 'canplay') { debugLog('EVENT[' + type + ']:' + event, 'event'); // We're no longer waiting for this media stream $('#videoPlayer').removeAttr('data-wait-' + type); // Check if we're ready to play all media checkAutoPlay(); if($('#videoPlayer')[0].hasAttribute('data-resume-play')) { var t = parseInt($('#videoPlayer').attr('data-resume-play')); triggerClappREvent('seek', t); triggerClappREvent('play'); $('#videoPlayer').removeAttr('data-resume-play'); } /* this.play(); this.removeAttribute('data-resume-play') // When switching qualities, we resume play once we're back at the same time if(this.hasAttribute('data-resume-play') && ! this.hasAttribute('data-reset-time')) { this.play(); this.removeAttribute('data-resume-play') } */ } if(event == 'play') { showVideo(); yvmtPlayerState('play', 'playing'); $('#videoPlayer').attr('data-play-status', 'play'); } if(event == 'pause') { yvmtPlayerState('play', 'paused'); $('#videoPlayer').attr('data-play-status', 'pause'); } if(event == 'time') { $('#videoPlayer [data-plyr="seek"]').attr('max', data.duration); $('#videoPlayer [data-plyr="seek"]').attr('value', data.time); $('#videoPlayer .plyr_time-current').html(printVideoTime(data.time)); storeWatchTime(data.time, data.duration); } if(event == 'ended') { if($('#checkin-flow').length > 0) { showVideoFeedbackSection(); } else if($(".post-emotion-modal").length > 0) { showVideoFeedbackSectionModal(); } } if(event == 'volumechange') { $('#videoPlayer [data-plyr="volume"]').attr('value', data); if(data == 0) { $('#videoPlayer').attr('data-mute-status', 'muted'); yvmtPlayerState('mute', 'muted'); } else { $('#videoPlayer').removeAttr('data-mute-status'); yvmtPlayerState('mute', 'unmuted'); } } if(event == 'level') { $('#videoPlayer .plyr_menu .dropdown-menu').children().removeClass('active'); $('#videoPlayer .plyr_menu .dropdown-menu [data-level=' + data + ']').addClass('active'); } if(type == 'video') { syncEventToAudioPlayer(event, data); } // logit(event); } function syncEventToAudioPlayer(event, data) { var aud = document.getElementById('audioTrack'); if(aud) { if(event == 'volumechange') { aud.volume = data; } if(event == 'play') { if(aud.readyState >= aud.HAVE_FUTURE_DATA) { playWithDebugLog('AUDIO SYNC', aud); logit('Trigger audio play', 'red'); } else { /// Wait for audio... logit('Audio not ready: ' + aud.readyState, 'red'); waitForAudio(); } } if(event == 'pause') { aud.pause(); debugLog('> Trigger audio pause (syncEventToAudioPlayer)', 'trigger'); } if(event == 'seek') { aud.currentTime = data.time; debugLog('set audio time: ' + data.time + '(' + aud.currentTime + ')'); } } } function playWithDebugLog(type, el) { var playPromise = el.play(); if (playPromise !== undefined) { playPromise.then(function() { debugLog('> ' + type + ' PLAY > SUCCESS', 'trigger'); } ).catch( function(error) { debugLog('> ' + type + ' PLAY > ERROR: ' + error, 'error'); } ); } } function printVideoTime(time) { var seconds = Math.floor(time); var minutes = Math.floor(seconds / 60); seconds -= (minutes * 60); return leadingZeros(minutes, 2) + ':' + leadingZeros(seconds, 2); } function leadingZeros(number, digits) { number = number.toString(); while(number.length < digits) { number = '0' + number; } return number; } function showVideo() { $('#videoLoading').css('display', 'none'); $('#videoPlayer').css('display', ''); $('#plyr_video-wrapper').height(Math.round($('#plyr_video-wrapper').width() / 2)); } function showAudio() { $('#videoLoading').css('display', 'none'); $('#videoPlayer').css('display', ''); // $('#audioTrack').prop('controls', true); } function waitForAudio() { debugLog('waitForAudio'); // We need to pause the video until the audio is loaded var aud = document.getElementById('audioTrack'); aud.setAttribute('data-buffering', 'true'); if(PlayerInstance) { PlayerInstance.pause(); } else { document.getElementById('vidEl').pause(); } } function pauseTrack(type) { if(type == 'audio') { var aud = document.getElementById('audioTrack'); aud.pause(); } else if(type == 'video') { if(PlayerInstance) { PlayerInstance.pause(); } else { document.getElementById('vidEl').pause(); } } } function playerCommand(command) { if(PlayerInstance) { var p = PlayerInstance; } else { var p = document.getElementById('vidEl'); } if(command == 'play') { p.play(); } else if(command == 'pause') { p.pause(); } } function playerStatus(status) { if(PlayerInstance) { var p = PlayerInstance; } else { var p = document.getElementById('vidEl'); } if(status == 'currentTime') { if(PlayerInstance) { return PlayerInstance.getCurrentTime(); } return p.currentTime; } } function getEmotionScores() { var str = ''; var fields = document.getElementsByClassName('emotionScore'); if(fields.length > 0) { for(var i = 0; i < fields.length; i++) { if(fields[i].checked) { str += '&emotions[' + fields[i].getAttribute('data-emotion') + ']=' + fields[i].value; } } } return str; } function uploadVideo(videoId, type) { var files = document.getElementById('videoUpload').files; if(files && files.length == 1) { var file = files[0]; var url = FULL_URL + '/admin/videos/getVideoUploadData?videoId=' + videoId + '&type=' + type; if(document.getElementById('includeDemo').checked) { url += '&includeDemo=1'; } url += '&filename=' + encodeURIComponent(file.name); ajaxRequest(url, function (myObject) { var xhr = new XMLHttpRequest(); xhr.onerror = function (e) { alert('XHR Connection error:' + e); }; xhr.upload.addEventListener('progress', function (e) { // handle notifications about upload progress: e.loaded / e.total document.getElementById('progressBar').style.width = (e.loaded / e.total * 100) + '%'; }, false); xhr.onreadystatechange = function () { if (xhr.readyState === XMLHttpRequest.DONE) { if (xhr.status >= 200 && xhr.status <= 299) { location.href = FULL_URL + '/admin/videos/edit?videoId=' + videoId; } else { // failed with error messge from server alert('Upload failed: ' + xhr.status); console.log(xhr); } } }; var formData = new FormData(); for (var id in myObject['s3Data']['inputs']) { formData.append(id, myObject['s3Data']['inputs'][id]); } formData.append('file', file); xhr.open('POST', myObject['s3Data']['form']['action'], true); xhr.send(formData); document.getElementById('uploadSelect').style.display = 'none'; document.getElementById('uploadProgress').style.display = 'block'; document.getElementById('progressBar').style.width = '0%'; } ); } else { alert('Please select a file'); } } /* function uploadAudio() { var files = document.getElementById('audioUpload').files; if(files && files.length > 0) { var file = files[0]; document.getElementById('uploadSelect').style.display = 'none'; document.getElementById('uploadProgress').style.display = 'block'; document.getElementById('progressBar').style.width = '0%'; ajaxRequest(FULL_URL + '/admin/audios/registerAudioUpload?title=' + encodeURIComponent(document.getElementById('title').value) + '&voiceId=' + parseInt(document.getElementById('voiceId').value) + '&categoryId=' + parseInt(document.getElementById('categoryId').value) + '&filename=' + encodeURIComponent(file.name) + getEmotionScores(), // SUCCESS function (myObject) { var xhr = new XMLHttpRequest(); xhr.onerror = function (e) { alert('XHR Connection error:' + e); }; xhr.upload.addEventListener('progress', function (e) { // handle notifications about upload progress: e.loaded / e.total document.getElementById('progressBar').style.width = (e.loaded / e.total * 100) + '%'; }, false); xhr.onreadystatechange = function () { if (xhr.readyState === XMLHttpRequest.DONE) { if (xhr.status >= 200 && xhr.status <= 299) { // location.href = FULL_URL + '/admin/audios/edit?audioId=' + myObject['audioId']; location.href = FULL_URL + '/admin/audios'; } else { // failed with error messge from server alert('Upload failed: ' + xhr.status); console.log(xhr); } } }; var formData = new FormData(); for (var id in myObject['s3Data']['inputs']) { formData.append(id, myObject['s3Data']['inputs'][id]); } formData.append('file', file); xhr.open('POST', myObject['s3Data']['form']['action'], true); xhr.send(formData); }, // ERROR function (myObject) { document.getElementById('uploadSelect').style.display = 'block'; document.getElementById('uploadProgress').style.display = 'none'; alert(myObject.error); } ); } else { alert('Please select a file'); } } */ function ajaxRequest(url, onComplete, onError, postParams) { var xhr = new XMLHttpRequest(); if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari var xmlhttp = new XMLHttpRequest(); } else { // code for IE6, IE5 var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } var method = 'GET'; if(postParams) { method = 'POST'; } xhr.open(method, encodeURI(url), true); if(method == 'POST' && typeof postParams == 'string') { xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); } xhr.onload = function() { if(xhr.status === 200) { if(JSON) { if(! JSON.parse && JSON.decode) { var myObject = JSON.decode(xhr.responseText); } else { var myObject = JSON.parse(xhr.responseText); } if(myObject.error && myObject.error.length > 0) { if(onError) { return onError(myObject); } alert(myObject.error); return false; } if(onComplete) { return onComplete(myObject); } } // unable to parse response return true; } else { return false; } }; if(postParams) { xhr.send(postParams); } else { xhr.send(); } } function audioReady(el) { debugLog('Audio Ready') $('#videoPlayer').removeAttr('data-wait-audio'); checkAutoPlay(); // The video was waiting for the audio to load... if(el.hasAttribute('data-buffering')) { // ... we can go now! el.removeAttribute('data-buffering'); playerCommand('play'); logit('Audio ready: Play video!', 'red'); } else { logit('Audio ready: No action [' + el.readyState + ']', 'red'); } } function audioTime(el) { // This only applies to the native player on oculus if(! PlayerInstance) { // If we detect the audio being ahead of the video, it is most likely oculus browser stuck without triggering "waiting" if(! el.paused) { var vid = document.getElementById('vidEl'); if(vid) { var videoTime = playerStatus('currentTime'); if(el.currentTime > (videoTime + 0.5)) { logit('Audio ahead.. video buffering? >> Pause audio', 'red'); debugLog('Audio ahead >> pause'); vid.setAttribute('data-buffering', 'true'); yvmtPlayerEvent('video', 'pause'); } } } } } function emotionClick(emotionId, tickbox) { if(tickbox.checked) { document.getElementById('emotionScore-' + emotionId).style.display = 'block'; document.getElementById('emotionScore-' + emotionId + '-5').checked = true; } else { document.getElementById('emotionScore-' + emotionId).style.display = 'none'; for(var score = 1; score <= 5; score++) { document.getElementById('emotionScore-' + emotionId + '-' + score).checked = false; } } } function initializeCheckinSteps() { // We have a fixed audio track if($('#fixedAudio').length > 0 && $('#checkin-flow').attr('data-user') != 'guest') { selectExperienceType('all'); } else { showCurrentCheckinStep(); } } function selectAudio(audioId, hasFemaleVoice, hasMaleVoice, btn) { $('#checkin-flow').attr('data-audio', audioId); var voicePreference = parseInt($('#checkin-flow').attr('data-voice-preference')); // Skip audio if(audioId == 0) { $('#checkin-flow').attr('data-experience-label', ''); $('#skipVideoBtn').css('display', 'none'); return audioSelected(); } $('#skipVideoBtn').css('display', ''); var showVoiceSelection = true; // In the demo, we skip the voice selection if($('#checkin-flow').attr('data-type') == 'demo') { showVoiceSelection = false; var selectedVoice = 0; } else { var selectedVoice = getSelectedVoice(hasFemaleVoice, hasMaleVoice, voicePreference); // In case we only have a female or male voice or the user has a fixed preference... if(selectedVoice > 0) { // ... no need to show voice selection showVoiceSelection = false; } } $('#checkin-flow').attr('data-experience-label', btn.getAttribute('data-experience-label')); if(showVoiceSelection) { showCurrentCheckinStep(4); } else { $('#checkin-flow').attr('data-voice', selectedVoice); audioSelected(); } } function audioSelected() { if($('#fixedVideo').length > 0) { selectVideo($('#fixedVideo').attr('data-video')); } else { showCurrentCheckinStep(5); } } function getSelectedVoice(hasFemaleVoice, hasMaleVoice, voicePreference) { if(! hasFemaleVoice) { return 2; } if(! hasMaleVoice) { return 1; } return voicePreference; } function selectVoice(voice) { $('#checkin-flow').attr('data-voice', voice); audioSelected(); } function selectVideoCategory(categoryId) { $('#checkin-flow').attr('data-video-category', categoryId); // No video if(categoryId == 0) { $('#checkin-flow').attr('data-video', 0); } // In the demo, we skip the actual video selection if($('#checkin-flow').attr('data-type') == 'demo' || categoryId == 0) { startCheckinVideoPlayer(); } else { $('#videosWrap').html(''); var url = FULL_URL + '/checkin/getVideos?type=' + $('#checkin-flow').attr('data-type') + '&categoryId=' + categoryId; ajaxRequest(url, function (myObject) { $('#videosWrap').html(myObject['response']); } ); showCurrentCheckinStep(6); } } function selectFavourite(el) { $('#checkin-flow').attr('data-audio', el.getAttribute('data-audio')); $('#checkin-flow').attr('data-voice', el.getAttribute('data-voice')); $('#checkin-flow').attr('data-video', el.getAttribute('data-video')); $('#checkin-flow').attr('data-video-category', 0); $('#checkin-flow').attr('data-experience-label', el.getAttribute('data-experience-label')); showCurrentCheckinStep(2); //startCheckinVideoPlayer(); } function replayVideo() { $('#checkin-flow').attr('data-type', 'replay'); $('#checkin-flow').attr('data-audio', $('#videoPlayer').attr('data-audio-id')); $('#checkin-flow').attr('data-video', $('#videoPlayer').attr('data-video-id')); $('#checkin-flow').attr('data-voice', $('#videoPlayer').attr('data-voice-id')); startCheckinVideoPlayer(); } function replayHomepageVideo(audioId, voiceId, videoId) { startVideoPlayer( { type: 'replay', audioId: audioId, voiceId: voiceId, videoId: videoId, autoPlay: true, emotionId: $(".pre-emotion-modal").attr('data-emotion') } ); $(".post-emotion-modal").modal('hide'); } function iPhoneDemoPlay() { startCheckinVideoPlayer(); $('#iphoneDemoInit').css('display', 'none'); $('#loadingImage').css('display', ''); } function initializeDemoVideo(type) { if(isIPhone() || 1==1) { if(type == 'what') { $('#experienceWaitLabel').html('What is YVMT?
Who is it for?'); } else { $('#experienceWaitLabel').html('Ready to create your 1-minute
360° taster experience'); } showCurrentCheckinStep(7); $('#iphoneDemoInit').css('display', ''); $('#loadingImage').css('display', 'none'); } else { startCheckinVideoPlayer(); } } function startCheckinVideoPlayer() { showCurrentCheckinStep(7); var type = $('#checkin-flow').attr('data-type'); var videoId = getIntAttr($('#checkin-flow'), 'data-video'); var videoCategoryId = getIntAttr($('#checkin-flow'), 'data-video-category'); var experienceLabel = $('#checkin-flow').attr('data-experience-label'); // Situations: // CHOOSE FOR ME: Label depends on the audio that will be chosen // NEW: Label from above // FAVOURITES Label depends on the favourite chosen: To be set when clicking favourite if(type == 'auto') { $('#experienceWaitLabel').html('I am creating your
360° experience'); } // else if (type == 'demo') { $('#experienceWaitLabel').html('I am creating your 1-minute
360° taster experience'); } else if (type == 'what') { $('#experienceWaitLabel').html('What is YVMT?
Who is it for?'); } // We use the video category here as well as guests do not select a specific video else if(videoId > 0 || videoCategoryId > 0) { $('#experienceWaitLabel').html('I am creating your
360° ' + experienceLabel + ' experience'); } else { $('#experienceWaitLabel').html('I am creating your
' + experienceLabel + ' audio experience'); } var params = { type : $('#checkin-flow').attr('data-type'), audioId : getIntAttr($('#checkin-flow'), 'data-audio'), voiceId : $('#checkin-flow').attr('data-voice'), videoId : videoId, videoCategoryId : videoCategoryId, emotionId : $('#checkin-flow').attr('data-emotion'), autoPlay : true }; startVideoPlayer(params); } function boolToInt(val) { if(val) { return 1; } return 0; } function setAdminPlayerBrowser() { $('#adminBrowser').val(getBrowserType()); } function initAdminPlayer() { var player = $('#adminPlayerSelection').val(); if(player == 'auto' ) { if(getBrowserType() == 'headset') { player = 'native'; } else { player = 'clappr'; } } if(player == 'clappr') { var wrap = document.getElementById('playerWrap'); wrap.innerHTML = '
'; var clappRParams = { source: $('#playerWrap').attr('data-url'), parentId: '#player', autoPlay: true, plugins: { 'core': [LevelSelector] } }; if($('#playerWrap').attr('data-type') == '360') { clappRParams.plugins.container = [Video360]; } PlayerInstance = new Clappr.Player(clappRParams); } else { var wrap = document.getElementById('playerWrap'); wrap.innerHTML = ''; var vid = document.createElement('VIDEO'); vid.src = $('#playerWrap').attr('data-url'); vid.controls = true; vid.autoplay = true; vid.style.width = '100%'; vid.id = 'vidEl'; wrap.appendChild(vid); } } function reportError() { var issue = prompt('Please describe issue:'); if(issue) { $.post( FULL_URL + '/player/report', { issue: issue, log: $('#debugMode').html(), browser: getBrowserType(), userAgent: navigator.userAgent, experience: $('#checkin-flow').attr('data-type'), emotion: $('#checkin-flow').attr('data-emotion'), time: $('#videoPlayer').attr('data-watched'), viewId: $('#videoPlayer').attr('data-view-id'), audioId: $('#videoPlayer').attr('data-audio-id'), voiceId: $('#videoPlayer').attr('data-voice-id'), versionId: $('#videoPlayer').attr('data-version-id'), videoId: $('#videoPlayer').attr('data-video-id') }, function(myObject) { console.log(myObject); if(myObject.error && myObject.error.length > 0) { alert(myObject.error); } else { alert(myObject.response); } }, 'json' ); } } function startVideoPlayer(params) { var browserType = getBrowserType(); $('#videoPlayer').attr('data-checkin-method', params.type); var url = FULL_URL + '/player/getPlayerData?m=' + params.type + '&a=' + params.audioId + '&b=' + browserType; if(params.voiceId) { url += '&s=' + params.voiceId; } if(params.videoCategoryId) { url += '&vc=' + params.videoCategoryId; } if(params.emotionId) { url += '&e=' + params.emotionId; } if(params.videoId) { url += '&v=' + params.videoId; } if(params.autoPlay) { url += '&ap=' + boolToInt(params.autoPlay); } if($('#enableDebugging').length > 0) { url += '&d=1'; } ajaxRequest(url, function (myObject) { // Init markup $('#videoPlayer').html(myObject['out']); initPlayerControls($('#videoPlayer')); if(myObject['isFavourite']) { yvmtPlayerState('favourite', 'favourite'); } $('#videoPlayer').attr('data-watched', 0); if(params.autoPlay) { $('#videoPlayer').attr('data-view-id', myObject['viewId']); $('#videoPlayer').attr('data-autoplay', 'true'); } else { $('#videoPlayer').attr('data-view-id', 'pending'); $('#videoPlayer').attr('data-autoplay', 'false'); } if(myObject['audio'] && myObject['video']) { $('#videoPlayer').attr('data-sync-audio', 'true'); } else { $('#videoPlayer').removeAttr('data-sync-audio'); } if(myObject['audio']) { $('#videoPlayer').attr('data-audio-id', myObject['audio']['audioId']); $('#videoPlayer').attr('data-voice-id', myObject['audio']['voiceId']); $('#videoPlayer').attr('data-version-id', myObject['audio']['versionId']); $('#videoPlayer').attr('data-wait-audio', 'true'); $('#audioPlayerWrap').html(''); var audio = document.createElement('AUDIO'); audio.id = 'audioTrack'; // This audios is played along a video if(myObject['video']) { // iOS doesn't load the audio automatically.. we need to trigger autoplay audio.setAttribute('data-wait-for-video', 'true'); // We'll cut off the autoplay once it starts (see comment above) audio.autoplay = true; audio.addEventListener('play', function(){ if(this.hasAttribute('data-wait-for-video')) { this.removeAttribute('data-wait-for-video'); if($('#videoPlayer').attr('data-wait-video') == 'true') { this.pause(); debugLog('> Trigger audio pause (data-wait-video)', 'trigger'); } else if($('#videoPlayer').attr('data-autoplay') != 'true' && $('#videoPlayer').attr('data-autoplay-started') != 'true') { this.pause(); debugLog('> Trigger audio pause (no autoplay)', 'trigger'); } } } ); audio.addEventListener('canplay', function(){ audioReady(this); } ); audio.addEventListener('canplaythrough', function(){ debugLog('AUDIO CAN PLAY THROUGH'); } ); audio.addEventListener('timeupdate', function(){ audioTime(this); } ); audio.addEventListener('waiting', function() { setMediaStreamBuffering('audio'); } ); } // This audio is played standalone in the main player else { addMainPlayerMediaEvents(audio, 'audio'); showAudio(); if(params.autoPlay) { audio.autoplay = true; } } audio.src = myObject['audio']['url']; $('#audioPlayerWrap').append(audio); } else { $('#videoPlayer').attr('data-audio-id', 0); $('#videoPlayer').attr('data-voice-id', 0); } if(myObject['video']) { $('#videoPlayer').attr('data-video-id', myObject['video']['videoId']); $('#videoPlayer').attr('data-video-pan', myObject['video']['urls']['pan']); $('#videoPlayer').attr('data-video-360', myObject['video']['urls']['360']); $('#videoPlayer').attr('data-wait-video', 'true'); if(browserType == 'headset') { playHeadsetVideo(myObject['video']['urls']['360']); } else { playClappRVideo(false, myObject['video']['urls']['pan']); } } else { $('#videoPlayer').attr('data-video-id', 0); } // iPhone doesn't buffer videos if there was no user interaction first if(isIPhone()) { // Demo mode shows the video immediately - an issue for iPhone if(params.type == 'demo' || params.type == 'what') { // -> Show video player // showVideo(); } } } ); } /* Either audio or video started buffering */ function setMediaStreamBuffering(type) { debugLog('setMediaStreamBuffering: ' + type); return false; // ONLY NEEDED IF WE HAVE TO SYNC AUDIO AND VIDEO if($('#videoPlayer').attr('data-sync-audio') == 'true') { debugLog('setMediaStreamBuffering: ' + type); // Mark which media stream is buffering // $('#videoPlayer').attr('data-wait-' + type, 'true'); // Set the video to start playing again once it is ready // $('#videoPlayer').attr('data-autplay', 'true'); // Stop the player // yvmtPlayerTriggerEvent('pause'); if(type == 'video') { pauseTrack('audio'); } else { pauseTrack('video'); } } } function trackVideoView(emotionId) { var url = FULL_URL + '/player/videoStart?m=' + $('#videoPlayer').attr('data-checkin-method') + '&b=' + getBrowserType() + '&v=' + getIntAttr($('#videoPlayer'), 'data-video-id') + '&av=' + getIntAttr($('#videoPlayer'), 'data-version-id') + '&e=' + emotionId; ajaxRequest(url, function (myObject) { $('#videoPlayer').attr('data-view-id', myObject['fullViewId']); } ); } function getBrowserType() { if(typeof emulateBrowser == 'string') { return emulateBrowser; } if(navigator.userAgent.match(/OculusBrowser/i) || navigator.userAgent.match(/Mobile VR/i)) { return 'headset'; } if(isIOS()) { return 'iphone'; } if(isAndroid()) { return 'android'; } return 'desktop'; } function isAndroid() { return navigator.userAgent.includes("Android"); } function getIntAttr(el, attr) { var attr = el.attr(attr); if (typeof attr !== typeof undefined && attr !== false) { return parseInt(attr); } return 0; } function selectVideo(videoId) { $('#checkin-flow').attr('data-video', videoId); startCheckinVideoPlayer(); } function showCurrentCheckinStep(step, fromHash) { if(fromHash) { // Check that this step exists if($('#checkin-step' + step).length > 0) { // In case the user left the page and the step has not be initialised, move to step 1 if(! $('#checkin-step' + step)[0].hasAttribute('data-init')) { location.hash = '#step-1'; return false; } } else { return false; } // We were on the player page if(parseInt($('#checkin-flow').attr('data-step')) == 7) { yvmtPlayerTriggerEvent('pause'); } } if(step) { $('#checkin-flow').attr('data-step', step); $('#checkin-step' + step).attr('data-init', 'true'); } location.hash = '#step-' + $('#checkin-flow').attr('data-step'); $('#checkin-flow').children().removeClass('active'); $('#checkin-step' + $('#checkin-flow').attr('data-step')).addClass('active'); var totalSteps = 6; if($('#checkin-flow').attr('data-type') == 'demo') { totalSteps = 3; } if(! checkinNavInit) { initCheckinNav(); } } function initCheckinNav() { checkinNavInit = true; window.addEventListener("hashchange", function() { var data = location.hash.split('-'); if(data[0] == '#step') { showCurrentCheckinStep(data[1], true); } }, false ); } function submitEmotion(el) { var emotionId = el.getAttribute('data-uid'); var positive = el.getAttribute('data-positive'); var question = el.getAttribute('data-post-question'); $('#checkin-flow').attr('data-emotion', emotionId); $('#checkin-flow').attr('data-emotion-positive', positive); // $('#post-experience-question').html(question); var type = $('#checkin-flow').attr('data-type'); // For "new experience" and the demo version, we show audios next if(type == 'new' || type == 'demo' || type == 'all') { // User came in for specific audio track if($('#fixedAudio').length > 0) { selectAudio( $('#fixedAudio').attr('data-audio'), parseInt($('#fixedAudio').attr('data-has-female')), parseInt($('#fixedAudio').attr('data-has-male')), $('#fixedAudio')[0] ); } else { $('#audioWrap').html(''); var url = FULL_URL + '/checkin/getAudios?type=' + $('#checkin-flow').attr('data-type') + '&emotionId=' + emotionId; if($('#fixedVideo').attr('data-admin') == 'true') { url += '&admin=1'; } ajaxRequest(url, function (myObject) { $('#audioWrap').html(myObject['response']); } ); showCurrentCheckinStep(3); } } // "choose for me" goes right to the player else if(type == 'auto') { startCheckinVideoPlayer(); } // Here we show the list of favourites else if(type == 'favourites') { startCheckinVideoPlayer(); // showCurrentCheckinStep('fav'); } } function loadFavourites() { var url = FULL_URL + '/checkin/getFavourites'; ajaxRequest(url, function (myObject) { $('#favouritesWrap').html(myObject['response']); } ); } function selectExperienceType(type) { $('#checkin-flow').attr('data-type', type); if(type == 'new' || type == 'all') { $('#checkin-flow').addClass('show-progress'); } else { $('#checkin-flow').removeClass('show-progress'); } if(type == 'all' || type == 'favourites') { $('#skipEmotionBtn').css('display', ''); } else { $('#skipEmotionBtn').css('display', 'none'); } if(type == 'favourites') { loadFavourites(); showCurrentCheckinStep('fav'); } else { showCurrentCheckinStep(2); } } function showFormWait(btnId) { document.getElementById(btnId).disabled = true; document.getElementById(btnId).innerHTML = 'please wait...'; } function uploadNew(btn, voiceId, withVideo) { btn.remove(); document.getElementById('uploadWrap-' + voiceId + '-' + withVideo).style.display = 'block'; } function showAudioInfo(e, audioId) { $('#audioModalText').html($('#audioInfo-' + audioId).html()); $('#audioModalTitle').html($('#audioInfo-' + audioId).attr('data-title')); $('#audioInfoModalOne').css('display', 'block'); $('#audioInfoModalOne').removeClass('fade'); e.stopPropagation(); } function closeInfoModal(id) { $('#' + id).addClass('fade'); $('#' + id).css('display', 'none'); } function playAudioVersion(btn, outputVersionId) { $('#audioVersion-' + outputVersionId).css('display', 'block'); btn.remove(); $('#audioVersion-' + outputVersionId)[0].play(); } function initMenuHighlighting() { $(document).ready( function () { topMenu = $("#top-menu"); topMenuHeight = topMenu.outerHeight()+15; scrollItems = []; $("#top-menu").find('a').each( function() { var href = $(this).attr("href").split('#'); if(href.length == 2) { var item = $('#' + href[1]); if (item.length) { scrollItems.push( [ item, $(this) ] ); } } } ); $(window).scroll(function(){ // Get container scroll position var fromTop = $(this).scrollTop()+topMenuHeight + 60; $("#top-menu").children().removeClass('active'); // Get id of current scroll item var cur = getCurrentScrollItem(fromTop); if(cur) { cur.parent().addClass('active'); } else { $("#top-menu").children().first().addClass('active'); } }); } ); } function getCurrentScrollItem(fromTop) { for(var i = scrollItems.length - 1; i >= 0; i--) { if ($(scrollItems[i][0]).offset().top < fromTop) { return scrollItems[i][1]; } } return false; } function showImgUpload(btn, type) { btn.parentNode.remove(); $('#uploadLogo-' + type).css('display', 'block'); } function selectUserType(el) { if(parseInt(el.value) == 9) { $('#adminOptions').css('display', 'block'); $('#debugWrap').css('display', 'none'); } else { $('#adminOptions').css('display', 'none'); $('#debugWrap').css('display', ''); } if(parseInt(el.value) == 2) { $('#orgWrap').css('display', ''); } else { $('#orgWrap').css('display', 'none'); } if(parseInt(el.value) == 5) { $('#ambassWrap').css('display', ''); } else { $('#ambassWrap').css('display', 'none'); } } function selectArticleSection(el) { $('#categoryOptions').html('Please wait...'); var url = FULL_URL + '/admin/articles/getCategories?sectionId=' + el.value; ajaxRequest(url, function (myObject) { $('#categoryOptions').html(myObject['response']); } ); } function initCKEditor(id) { ClassicEditor .create( document.querySelector( '#' + id ),{ toolbar: [ 'heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', '|', 'imageUpload', 'MediaEmbed', 'MediaEmbed', '|', 'undo', 'redo' ], extraPlugins: [ YvmtUploadAdapterPlugin ], mediaEmbed: { previewsInData: true } } ) .then( id => { console.log( Array.from( id.ui.componentFactory.names() ) ); } ) .catch( error => { console.error( error ); } ); } function triggerClappREvent(e, value) { if(e == 'play') { PlayerInstance.play(); } if(e == 'pause') { PlayerInstance.pause(); } if(e == 'seek') { PlayerInstance.seek(value); } if(e == 'fullscreen') { PlayerInstance.core.mediaControl.toggleFullscreen(); } if(e == 'volume') { PlayerInstance.setVolume(value * 100); } } function triggerNativeEvent(mediaElement, e, value) { if(e == 'play') { mediaElement.trigger('play'); } if(e == 'pause') { mediaElement.trigger('pause'); } if(e == 'seek') { mediaElement.get(0).currentTime = value; } if(e == 'fullscreen') { goFullscreen(mediaElement.get(0)); } if(e == 'volume') { mediaElement.prop('volume', value); } } function yvmtPlayerTriggerEvent(e, el) { var value = false; if(el && el.value) { value = el.value; debugLog('> EVENT TRIGGERED: ' + e + '[' + value + ']', 'trigger'); } else { debugLog('> EVENT TRIGGERED: ' + e, 'trigger'); } if(e == 'play') { // Allow toggling between play and pause if($('#videoPlayer').attr('data-play-status') == 'play') { e = 'pause'; debugLog('>> PLAY/PAUSE toggle >> pause', 'trigger'); } } if(PlayerInstance) { triggerClappREvent(e, value) } else if($('#vidEl').length > 0) { triggerNativeEvent($('#vidEl'), e, value); } else if($('#audioTrack').length > 0) { triggerNativeEvent($('#audioTrack'), e, value); } if(e == '360') { switchPlayer(); } if(e == 'mute') { if($('#videoPlayer').attr('data-mute-status') == 'muted') { yvmtPlayerTriggerEvent('volume', {value: 1}); } else { yvmtPlayerTriggerEvent('volume', {value: 0}); } } if(e == 'favourite') { if($(el).attr('data-state') == 'favourite') { updateFavouriteState(0); yvmtPlayerState('favourite', 'not'); } else { updateFavouriteState(1); yvmtPlayerState('favourite', 'favourite'); } } } function updateFavouriteState(favourite) { var audioId = $('#videoPlayer').attr('data-audio-id'); var voiceId = $('#videoPlayer').attr('data-voice-id'); var videoId = $('#videoPlayer').attr('data-video-id'); var url = FULL_URL + '/player/favourite?videoId=' + videoId + '&audioId=' + audioId + '&voiceId=' + voiceId + '&favourite=' + favourite; ajaxRequest(url); } function initPlayerControls(wrapper) { wrapper.find('[data-plyr]').each( function() { var e = this.getAttribute('data-plyr'); var event = 'click'; if(e == 'volume' || e == 'seek') { event = 'input'; } this.addEventListener(event, function() { yvmtPlayerTriggerEvent(e, this); } ); } ); // Hide levels until we know they are available $('#videoPlayer .plyr_menu').css('display', 'none'); } function updatePlayerQualityLevels(levels) { if(levels && levels.length > 0) { $('#videoPlayer .plyr_menu').css('display', ''); var dropdown = $('#videoPlayer .plyr_menu .dropdown-menu') dropdown.html(''); var a = document.createElement('a'); a.className = 'dropdown-item active'; a.innerHTML = 'auto'; a.setAttribute('data-level', -1); a.addEventListener('click', function () { triggerQualityLevel(this.getAttribute('data-level')); } ); dropdown.append(a); for(var i = 0; i < levels.length; i++) { var a = document.createElement('a'); a.className = 'dropdown-item'; a.innerHTML = levels[i].label; a.setAttribute('data-level', levels[i].id); a.addEventListener('click', function () { triggerQualityLevel(parseInt(this.getAttribute('data-level'))); } ); dropdown.append(a); } } else { $('#videoPlayer .plyr_menu').css('display', 'none'); } } function triggerQualityLevel(level) { if(PlayerInstance) { PlayerInstance.core.activePlayback.currentLevel = level; } else { lockQuality(level); } } function showVideoFeedbackSection() { $('#postViewFeedbackWrap').css('display', 'none'); showCurrentCheckinStep(8); } function showVideoFeedbackSectionModal() { $('#postViewFeedbackWrap').css('display', 'none'); $(".post-emotion-modal").modal(); } function submitPostEmotion(emotionChange) { var viewId = $('#videoPlayer').attr('data-view-id'); var url = FULL_URL + '/player/postViewEmotion?v=' + viewId + '&e=' + emotionChange + '&i=' + improvementParameter(emotionChange); ajaxRequest(url); $('#positiveFeedbackBtn').css('display', 'none'); $('#nonPositiveFeedbackBtn').css('display', 'none'); // if(emotionChange == emotionImprovementResponse) // Emotion improved if(emotionChange == 3) { $('#positiveFeedbackBtn').css('display', ''); } else { $('#nonPositiveFeedbackBtn').css('display', ''); } $('#postViewFeedbackWrap').css('display', 'block'); } function improvementParameter(emotionChange) { // 3->1 // 2->0 // 1->-1 return emotionChange - 2; } function getImprovementForEmotion(positiveEmotion, emotionChange) { // "somewhat equal" if(emotionChange == 2) { // ... is always neutral return 0; } // Positive emotion: Higher if(positiveEmotion && emotionChange == 3) { // ... is an improvement return 1; } // Negative emotion: Lower if(! positiveEmotion && emotionChange == 1) { // ... is an improvement return 1; } // Otherwise: Worsened return -1; } /*** IMAGE UPLOADER ***/ class YvmtUploadAdapter { constructor( loader ) { // The file loader instance to use during the upload. this.loader = loader; } // Starts the upload process. upload() { return this.loader.file .then( file => new Promise( ( resolve, reject ) => { this._initRequest(); this._initListeners( resolve, reject, file ); this._sendRequest( file ); } ) ); } // Aborts the upload process. abort() { if ( this.xhr ) { this.xhr.abort(); } } // Initializes the XMLHttpRequest object using the URL passed to the constructor. _initRequest() { const xhr = this.xhr = new XMLHttpRequest(); // Note that your request may look different. It is up to you and your editor // integration to choose the right communication channel. This example uses // a POST request with JSON as a data structure but your configuration // could be different. xhr.open( 'POST', FULL_URL + '/admin/articles/uploadImage', true ); xhr.responseType = 'json'; } // Initializes XMLHttpRequest listeners. _initListeners( resolve, reject, file ) { const xhr = this.xhr; const loader = this.loader; const genericErrorText = `Couldn't upload file: ${ file.name }.`; xhr.addEventListener( 'error', () => reject( genericErrorText ) ); xhr.addEventListener( 'abort', () => reject() ); xhr.addEventListener( 'load', () => { const response = xhr.response; // This example assumes the XHR server's "response" object will come with // an "error" which has its own "message" that can be passed to reject() // in the upload promise. // // Your integration may handle upload errors in a different way so make sure // it is done properly. The reject() function must be called when the upload fails. if ( !response || response.error ) { return reject( response && response.error ? response.error : genericErrorText ); } // If the upload is successful, resolve the upload promise with an object containing // at least the "default" URL, pointing to the image on the server. // This URL will be used to display the image in the content. Learn more in the // UploadAdapter#upload documentation. resolve( { default: response.url } ); } ); // Upload progress when it is supported. The file loader has the #uploadTotal and #uploaded // properties which are used e.g. to display the upload progress bar in the editor // user interface. if ( xhr.upload ) { xhr.upload.addEventListener( 'progress', evt => { if ( evt.lengthComputable ) { loader.uploadTotal = evt.total; loader.uploaded = evt.loaded; } } ); } } // Prepares the data and sends the request. _sendRequest( file ) { // Prepare the form data. const data = new FormData(); data.append( 'upload', file ); // Important note: This is the right place to implement security mechanisms // like authentication and CSRF protection. For instance, you can use // XMLHttpRequest.setRequestHeader() to set the request headers containing // the CSRF token generated earlier by your application. // Send the request. this.xhr.send( data ); } } // ... function YvmtUploadAdapterPlugin( editor ) { editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => { // Configure the URL to the upload script in your back-end here! return new YvmtUploadAdapter( loader ); }; } /*** IMAGE UPLOADER END ***/ function acceptCookies(acc) { $('.cookie-disclaimer').remove(); $('.gdpr-modal-lg').remove(); var scope = 'essential'; if(acc == 'all' || $('#measureCookiesBtn.active').length > 0) { scope = 'all'; } setCookie('acceptCookies', scope, 10 * 365); if(scope == 'all') { var url = FULL_URL + '/cookies?ga=1'; ajaxRequest(url, function (myObject) { $('body').prepend(myObject['response']); } ); } else { rmCookie('_ga'); } } function setCookie(cname, cvalue, exdays) { var d = new Date(); d.setTime(d.getTime() + (exdays*24*60*60*1000)); var expires = "expires="+ d.toUTCString(); document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; } function rmCookie(cname) { document.cookie = cname + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; } function rmDoc(docId) { if(confirm('You are about to remove this document\nWould you like to continue?')) { $('#documentWrap-' + docId).remove(); } } function addMoreDocs() { $('#docUploads').append(''); } function loadMoreUsageHistoryItems(el, start) { $(el).parent().html('please wait...'); var url = FULL_URL + '/account/moreHistory?start=' + start; ajaxRequest(url, function (myObject) { $('#moreHistoryWrap').remove(); $('#usageTable').append(myObject['response']); } ); } function applyStatsFilter(el) { var filter = el.getAttribute('data-filter'); var value = el.getAttribute('data-value'); $('#filter-' + filter).val(value); $('#filterForm').submit(); }