From b3a664583a3cc33466fdc1a6d50fbeba69d71cd0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 3 Jan 2017 01:39:59 -0500 Subject: [PATCH] add osd files --- dashboard-ui/scripts/videoosd.js | 1086 ++++++++++++++++++++++++++++++ dashboard-ui/videoosd.html | 62 ++ 2 files changed, 1148 insertions(+) create mode 100644 dashboard-ui/scripts/videoosd.js create mode 100644 dashboard-ui/videoosd.html diff --git a/dashboard-ui/scripts/videoosd.js b/dashboard-ui/scripts/videoosd.js new file mode 100644 index 0000000000..d8b5e6abf6 --- /dev/null +++ b/dashboard-ui/scripts/videoosd.js @@ -0,0 +1,1086 @@ +define(['playbackManager', 'dom', 'inputmanager', 'datetime', 'itemHelper', 'mediaInfo', 'focusManager', 'imageLoader', 'scrollHelper', 'events', 'connectionManager', 'browser', 'globalize', 'apphost', 'scrollStyles'], function (playbackManager, dom, inputManager, datetime, itemHelper, mediaInfo, focusManager, imageLoader, scrollHelper, events, connectionManager, browser, globalize, appHost) { + 'use strict'; + + function seriesImageUrl(item, options) { + + if (item.Type !== 'Episode') { + return null; + } + + options = options || {}; + options.type = options.type || "Primary"; + + if (options.type === 'Primary') { + + if (item.SeriesPrimaryImageTag) { + + options.tag = item.SeriesPrimaryImageTag; + + return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); + } + } + + if (options.type === 'Thumb') { + + if (item.SeriesThumbImageTag) { + + options.tag = item.SeriesThumbImageTag; + + return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.SeriesId, options); + } + if (item.ParentThumbImageTag) { + + options.tag = item.ParentThumbImageTag; + + return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.ParentThumbItemId, options); + } + } + + return null; + } + + function imageUrl(item, options) { + + options = options || {}; + options.type = options.type || "Primary"; + + if (item.ImageTags && item.ImageTags[options.type]) { + + options.tag = item.ImageTags[options.type]; + return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.Id, options); + } + + if (options.type === 'Primary') { + if (item.AlbumId && item.AlbumPrimaryImageTag) { + + options.tag = item.AlbumPrimaryImageTag; + return connectionManager.getApiClient(item.ServerId).getScaledImageUrl(item.AlbumId, options); + } + } + + return null; + } + + function logoImageUrl(item, apiClient, options) { + + options = options || {}; + options.type = "Logo"; + + if (item.ImageTags && item.ImageTags.Logo) { + + options.tag = item.ImageTags.Logo; + return apiClient.getScaledImageUrl(item.Id, options); + } + + if (item.ParentLogoImageTag) { + options.tag = item.ParentLogoImageTag; + return apiClient.getScaledImageUrl(item.ParentLogoItemId, options); + } + + return null; + } + + return function (view, params) { + + var self = this; + var currentPlayer; + var currentPlayerSupportedCommands = []; + var currentRuntimeTicks = 0; + var lastUpdateTime = 0; + var lastPlayerState = {}; + var isEnabled; + var currentItem; + + var nowPlayingVolumeSlider = view.querySelector('.osdVolumeSlider'); + var nowPlayingVolumeSliderContainer = view.querySelector('.osdVolumeSliderContainer'); + + var nowPlayingPositionSlider = view.querySelector('.osdPositionSlider'); + + var nowPlayingPositionText = view.querySelector('.osdPositionText'); + var nowPlayingDurationText = view.querySelector('.osdDurationText'); + var endsAtText = view.querySelector('.endsAtText'); + + var scenePicker = view.querySelector('.scenePicker'); + var isScenePickerRendered; + var btnRewind = view.querySelector('.btnRewind'); + var btnFastForward = view.querySelector('.btnFastForward'); + + var transitionEndEventName = dom.whichTransitionEvent(); + + function getHeaderElement() { + return document.querySelector('.skinHeader'); + } + + function getOsdBottom() { + return view.querySelector('.videoOsdBottom'); + } + + function updateNowPlayingInfo(state) { + + scenePicker.innerHTML = ''; + isScenePickerRendered = false; + + var item = state.NowPlayingItem; + + setPoster(item); + + if (!item) { + Emby.Page.setTitle(''); + nowPlayingVolumeSlider.disabled = true; + nowPlayingPositionSlider.disabled = true; + btnFastForward.disabled = true; + btnRewind.disabled = true; + + view.querySelector('.btnSubtitles').classList.add('hide'); + view.querySelector('.btnAudio').classList.add('hide'); + + view.querySelector('.osdTitle').innerHTML = ''; + view.querySelector('.osdMediaInfo').innerHTML = ''; + return; + } + + setTitle(item); + + view.querySelector('.osdTitle').innerHTML = itemHelper.getDisplayName(item); + view.querySelector('.osdMediaInfo').innerHTML = mediaInfo.getPrimaryMediaInfoHtml(item, { + runtime: false, + subtitles: false, + tomatoes: false, + endsAt: false + }); + + nowPlayingVolumeSlider.disabled = false; + nowPlayingPositionSlider.disabled = false; + btnFastForward.disabled = false; + btnRewind.disabled = false; + + if (playbackManager.subtitleTracks(currentPlayer).length) { + view.querySelector('.btnSubtitles').classList.remove('hide'); + } else { + view.querySelector('.btnSubtitles').classList.add('hide'); + } + + if (playbackManager.audioTracks(currentPlayer).length > 1) { + view.querySelector('.btnAudio').classList.remove('hide'); + } else { + view.querySelector('.btnAudio').classList.add('hide'); + } + + } + + function setTitle(item) { + + var url = logoImageUrl(item, connectionManager.getApiClient(item.ServerId), {}); + + if (url) { + + var pageTitle = document.querySelector('.pageTitle'); + pageTitle.style.backgroundImage = "url('" + url + "')"; + pageTitle.classList.add('pageTitleWithLogo'); + pageTitle.innerHTML = ''; + document.querySelector('.headerLogo').classList.add('hide'); + } else { + Emby.Page.setTitle(''); + } + } + + function setPoster(item) { + + var osdPoster = view.querySelector('.osdPoster'); + + if (item) { + + var imgUrl = seriesImageUrl(item, { type: 'Primary' }) || + seriesImageUrl(item, { type: 'Thumb' }) || + imageUrl(item, { type: 'Primary' }); + + if (imgUrl) { + osdPoster.innerHTML = ''; + return; + } + } + + osdPoster.innerHTML = ''; + } + + var _osdOpen = true; + + function isOsdOpen() { + return _osdOpen; + } + + function showOsd() { + + slideDownToShow(getHeaderElement()); + slideUpToShow(getOsdBottom()); + startHideTimer(); + } + + function hideOsd() { + + slideUpToHide(getHeaderElement()); + slideDownToHide(getOsdBottom()); + } + + var hideTimeout; + + function startHideTimer() { + stopHideTimer(); + hideTimeout = setTimeout(hideOsd, 5000); + } + + function stopHideTimer() { + if (hideTimeout) { + clearTimeout(hideTimeout); + hideTimeout = null; + } + } + + function slideDownToShow(elem) { + + elem.classList.remove('osdHeader-hidden'); + } + + function slideUpToHide(elem) { + + elem.classList.add('osdHeader-hidden'); + } + + function clearBottomPanelAnimationEventListeners(elem) { + + dom.removeEventListener(elem, transitionEndEventName, onSlideDownComplete, { + once: true + }); + } + + function slideUpToShow(elem) { + + if (_osdOpen) { + return; + } + + _osdOpen = true; + + clearBottomPanelAnimationEventListeners(elem); + + elem.classList.remove('hide'); + + // trigger a reflow to force it to animate again + void elem.offsetWidth; + + elem.classList.remove('videoOsdBottom-hidden'); + + focusManager.focus(elem.querySelector('.btnPause')); + + view.dispatchEvent(new CustomEvent('video-osd-show', { + bubbles: true, + cancelable: false + })); + } + + function onSlideDownComplete(e) { + + var elem = e.target; + + elem.classList.add('hide'); + + dom.removeEventListener(elem, transitionEndEventName, onSlideDownComplete, { + once: true + }); + + view.dispatchEvent(new CustomEvent('video-osd-hide', { + bubbles: true, + cancelable: false + })); + } + + function slideDownToHide(elem) { + + if (!_osdOpen) { + return; + } + + clearBottomPanelAnimationEventListeners(elem); + + // trigger a reflow to force it to animate again + void elem.offsetWidth; + + elem.classList.add('videoOsdBottom-hidden'); + + dom.addEventListener(elem, transitionEndEventName, onSlideDownComplete, { + once: true + }); + + _osdOpen = false; + } + + var lastMouseMoveData; + + function onMouseMove(e) { + + var eventX = e.screenX || 0; + var eventY = e.screenY || 0; + + var obj = lastMouseMoveData; + if (!obj) { + lastMouseMoveData = { + x: eventX, + y: eventY + }; + return; + } + + // if coord are same, it didn't move + if (Math.abs(eventX - obj.x) < 10 && Math.abs(eventY - obj.y) < 10) { + return; + } + + obj.x = eventX; + obj.y = eventY; + + showOsd(); + } + + function onInputCommand(e) { + + switch (e.detail.command) { + + case 'left': + if (isOsdOpen()) { + showOsd(); + } else { + e.preventDefault(); + playbackManager.rewind(); + } + break; + case 'right': + if (isOsdOpen()) { + showOsd(); + } else { + e.preventDefault(); + playbackManager.fastForward(); + } + break; + case 'up': + case 'down': + case 'select': + case 'menu': + case 'info': + case 'play': + case 'playpause': + case 'pause': + case 'fastforward': + case 'rewind': + case 'next': + case 'previous': + showOsd(); + break; + default: + break; + } + } + + view.addEventListener('viewbeforeshow', function (e) { + + getHeaderElement().classList.add('osdHeader'); + // Make sure the UI is completely transparent + Emby.Page.setTransparency('full'); + }); + + view.addEventListener('viewshow', function (e) { + + events.on(playbackManager, 'playerchange', onPlayerChange); + bindToPlayer(playbackManager.getCurrentPlayer()); + + document.addEventListener('mousemove', onMouseMove); + + showOsd(); + + inputManager.on(window, onInputCommand); + }); + + view.addEventListener('viewbeforehide', function () { + stopHideTimer(); + getHeaderElement().classList.remove('osdHeader'); + getHeaderElement().classList.remove('osdHeader-hidden'); + document.removeEventListener('mousemove', onMouseMove); + + inputManager.off(window, onInputCommand); + events.off(playbackManager, 'playerchange', onPlayerChange); + releaseCurrentPlayer(); + }); + + function onPlayerChange() { + bindToPlayer(playbackManager.getCurrentPlayer()); + } + + function onStateChanged(event, state) { + + //console.log('nowplaying event: ' + e.type); + var player = this; + + if (!state.NowPlayingItem) { + return; + } + + isEnabled = true; + + updatePlayerStateInternal(event, state); + updatePlaylist(); + + playbackManager.beginPlayerUpdates(player); + + enableStopOnBack(true); + } + + function onPlayPauseStateChanged(e) { + + if (!isEnabled) { + return; + } + + var player = this; + updatePlayPauseState(player.paused()); + } + + function onVolumeChanged(e) { + + if (!isEnabled) { + return; + } + + var player = this; + + updatePlayerVolumeState(player.isMuted(), player.getVolume()); + } + + function onPlaybackStart(e, state) { + + console.log('nowplaying event: ' + e.type); + + var player = this; + + onStateChanged.call(player, e, state); + } + + function onPlaybackStopped(e, state) { + + console.log('nowplaying event: ' + e.type); + var player = this; + + playbackManager.endPlayerUpdates(player); + + if (state.nextMediaType !== 'Video') { + + view.removeEventListener('viewbeforehide', onViewHideStopPlayback); + + Emby.Page.back(); + } + } + + function bindToPlayer(player) { + + if (player === currentPlayer) { + return; + } + + releaseCurrentPlayer(); + + currentPlayer = player; + + if (!player) { + return; + } + + playbackManager.getPlayerState(player).then(function (state) { + + onStateChanged.call(player, { type: 'init' }, state); + }); + + events.on(player, 'playbackstart', onPlaybackStart); + events.on(player, 'playbackstop', onPlaybackStopped); + events.on(player, 'volumechange', onVolumeChanged); + events.on(player, 'pause', onPlayPauseStateChanged); + events.on(player, 'playing', onPlayPauseStateChanged); + events.on(player, 'timeupdate', onTimeUpdate); + } + + function releaseCurrentPlayer() { + + var player = currentPlayer; + + if (player) { + + events.off(player, 'playbackstart', onPlaybackStart); + events.off(player, 'playbackstop', onPlaybackStopped); + events.off(player, 'volumechange', onVolumeChanged); + events.off(player, 'pause', onPlayPauseStateChanged); + events.off(player, 'playing', onPlayPauseStateChanged); + events.off(player, 'timeupdate', onTimeUpdate); + + playbackManager.endPlayerUpdates(player); + currentPlayer = null; + } + } + + function onTimeUpdate(e) { + + if (!isEnabled) { + return; + } + + // Try to avoid hammering the document with changes + var now = new Date().getTime(); + if ((now - lastUpdateTime) < 700) { + + return; + } + lastUpdateTime = now; + + var player = this; + var state = lastPlayerState; + var nowPlayingItem = state.NowPlayingItem || {}; + currentRuntimeTicks = playbackManager.duration(player); + updateTimeDisplay(playbackManager.currentTime(player), currentRuntimeTicks); + } + + function updatePlayPauseState(isPaused) { + + if (isPaused) { + view.querySelector('.btnPause i').innerHTML = ''; + } else { + view.querySelector('.btnPause i').innerHTML = ''; + } + } + + function updatePlayerStateInternal(event, state) { + + lastPlayerState = state; + + var playerInfo = playbackManager.getPlayerInfo(); + + var playState = state.PlayState || {}; + + updatePlayPauseState(playState.IsPaused); + + var supportedCommands = playerInfo.supportedCommands; + currentPlayerSupportedCommands = supportedCommands; + + //if (supportedCommands.indexOf('SetRepeatMode') == -1) { + // toggleRepeatButton.classList.add('hide'); + //} else { + // toggleRepeatButton.classList.remove('hide'); + //} + + //if (playState.RepeatMode == 'RepeatAll') { + // toggleRepeatButtonIcon.innerHTML = "repeat"; + // toggleRepeatButton.classList.add('repeatActive'); + //} + //else if (playState.RepeatMode == 'RepeatOne') { + // toggleRepeatButtonIcon.innerHTML = "repeat_one"; + // toggleRepeatButton.classList.add('repeatActive'); + //} else { + // toggleRepeatButtonIcon.innerHTML = "repeat"; + // toggleRepeatButton.classList.remove('repeatActive'); + //} + + updatePlayerVolumeState(playState.IsMuted, playState.VolumeLevel); + + if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) { + nowPlayingPositionSlider.disabled = !playState.CanSeek; + } + + btnFastForward.disabled = !playState.CanSeek; + btnRewind.disabled = !playState.CanSeek; + + var nowPlayingItem = state.NowPlayingItem || {}; + updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks); + + updateNowPlayingInfo(state); + } + + function updateTimeDisplay(positionTicks, runtimeTicks) { + + if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) { + if (runtimeTicks) { + + var pct = positionTicks / runtimeTicks; + pct *= 100; + + nowPlayingPositionSlider.value = pct; + + } else { + + nowPlayingPositionSlider.value = 0; + } + + if (runtimeTicks && positionTicks != null) { + endsAtText.innerHTML = '  -  ' + mediaInfo.getEndsAtFromPosition(runtimeTicks, positionTicks, true); + } else { + endsAtText.innerHTML = ''; + } + } + + updateTimeText(nowPlayingPositionText, positionTicks); + updateTimeText(nowPlayingDurationText, runtimeTicks, true); + } + + function updatePlayerVolumeState(isMuted, volumeLevel) { + + var supportedCommands = currentPlayerSupportedCommands; + + var showMuteButton = true; + var showVolumeSlider = true; + + if (supportedCommands.indexOf('Mute') === -1) { + showMuteButton = false; + } + + if (supportedCommands.indexOf('SetVolume') === -1) { + showVolumeSlider = false; + } + + if (currentPlayer.isLocalPlayer && appHost.supports('physicalvolumecontrol')) { + showMuteButton = false; + showVolumeSlider = false; + } + + if (isMuted) { + view.querySelector('.buttonMute i').innerHTML = ''; + } else { + view.querySelector('.buttonMute i').innerHTML = ''; + } + + if (showMuteButton) { + view.querySelector('.buttonMute').classList.remove('hide'); + } else { + view.querySelector('.buttonMute').classList.add('hide'); + } + + // See bindEvents for why this is necessary + if (nowPlayingVolumeSlider) { + + if (showVolumeSlider) { + nowPlayingVolumeSliderContainer.classList.remove('hide'); + } else { + nowPlayingVolumeSliderContainer.classList.add('hide'); + } + + if (!nowPlayingVolumeSlider.dragging) { + nowPlayingVolumeSlider.value = volumeLevel || 0; + } + } + } + + function updatePlaylist() { + + var items = playbackManager.playlist(); + + var index = playbackManager.currentPlaylistIndex(); + + var previousEnabled = index > 0; + var nextEnabled = (index < items.length - 1); + + var btnPreviousTrack = view.querySelector('.btnPreviousTrack'); + var btnNextTrack = view.querySelector('.btnNextTrack'); + + if (!nextEnabled && !previousEnabled) { + + btnPreviousTrack.classList.add('hide'); + btnNextTrack.classList.add('hide'); + + } else { + + btnPreviousTrack.classList.remove('hide'); + btnNextTrack.classList.remove('hide'); + + btnNextTrack.disabled = !nextEnabled; + btnPreviousTrack.disabled = !previousEnabled; + } + } + + function updateTimeText(elem, ticks, divider) { + + if (ticks == null) { + elem.innerHTML = ''; + return; + } + + var html = datetime.getDisplayRunningTime(ticks); + + if (divider) { + html = ' / ' + html; + } + + elem.innerHTML = html; + } + + function showAudioTrackSelection() { + + var player = currentPlayer; + + var audioTracks = lastPlayerState.MediaSource.MediaStreams.filter(function (s) { + return s.Type === 'Audio'; + }); + + var currentIndex = playbackManager.getAudioStreamIndex(player); + + var menuItems = audioTracks.map(function (stream) { + + var opt = { + name: stream.DisplayTitle, + id: stream.Index + }; + + if (stream.Index === currentIndex) { + opt.selected = true; + } + + return opt; + }); + + require(['actionsheet'], function (actionsheet) { + + actionsheet.show({ + items: menuItems, + title: globalize.translate('Audio') + }).then(function (id) { + var index = parseInt(id); + if (index !== currentIndex) { + playbackManager.setAudioStreamIndex(index, currentPlayer); + } + }); + }); + } + + function showSubtitleTrackSelection() { + + var player = currentPlayer; + + var streams = lastPlayerState.MediaSource.MediaStreams.filter(function (s) { + return s.Type === 'Subtitle'; + }); + + var currentIndex = playbackManager.getSubtitleStreamIndex(player); + if (currentIndex == null) { + currentIndex = -1; + } + + streams.unshift({ + Index: -1, + DisplayTitle: globalize.translate('Off') + }); + + var menuItems = streams.map(function (stream) { + + var opt = { + name: stream.DisplayTitle, + id: stream.Index + }; + + if (stream.Index === currentIndex) { + opt.selected = true; + } + + return opt; + }); + + require(['actionsheet'], function (actionsheet) { + + actionsheet.show({ + title: globalize.translate('Subtitles'), + items: menuItems + }).then(function (id) { + var index = parseInt(id); + if (index !== currentIndex) { + playbackManager.setSubtitleStreamIndex(index, currentPlayer); + } + }); + + }); + } + + view.addEventListener('viewhide', function () { + + getHeaderElement().classList.remove('hide'); + }); + + dom.addEventListener(window, 'keydown', function (e) { + + if (e.keyCode === 32 && !isOsdOpen()) { + playbackManager.playPause(currentPlayer); + showOsd(); + } + }, { + passive: true + }); + + view.querySelector('.pageContainer').addEventListener('click', function () { + + playbackManager.playPause(currentPlayer); + showOsd(); + }); + + view.querySelector('.buttonMute').addEventListener('click', function () { + + playbackManager.toggleMute(currentPlayer); + }); + + nowPlayingVolumeSlider.addEventListener('change', function () { + + playbackManager.setVolume(this.value, currentPlayer); + }); + + nowPlayingPositionSlider.addEventListener('change', function () { + + stopScenePickerTimer(); + if (currentPlayer) { + + var newPercent = parseFloat(this.value); + + playbackManager.seekPercent(newPercent, currentPlayer); + } + }); + + nowPlayingPositionSlider.getBubbleText = function (value) { + + var state = lastPlayerState; + + if (!state || !state.NowPlayingItem || !currentRuntimeTicks) { + return '--:--'; + } + + var ticks = currentRuntimeTicks; + ticks /= 100; + ticks *= value; + + return datetime.getDisplayRunningTime(ticks); + }; + + view.querySelector('.btnPreviousTrack').addEventListener('click', function () { + + playbackManager.previousChapter(currentPlayer); + }); + + view.querySelector('.btnPause').addEventListener('click', function () { + + playbackManager.playPause(currentPlayer); + }); + + view.querySelector('.btnNextTrack').addEventListener('click', function () { + + playbackManager.nextChapter(currentPlayer); + }); + + btnRewind.addEventListener('click', function () { + + playbackManager.rewind(currentPlayer); + }); + + btnFastForward.addEventListener('click', function () { + + playbackManager.fastForward(currentPlayer); + }); + + view.querySelector('.btnAudio').addEventListener('click', showAudioTrackSelection); + view.querySelector('.btnSubtitles').addEventListener('click', showSubtitleTrackSelection); + + function getChapterHtml(item, chapter, index, maxWidth, apiClient) { + + var html = ''; + + var src = getImgUrl(item, chapter, index, maxWidth, apiClient); + + if (src) { + + var pct = currentRuntimeTicks ? (chapter.StartPositionTicks / currentRuntimeTicks) : 0; + pct *= 100; + chapterPcts[index] = pct; + + html += ''; + } + + return html; + } + + function getImgUrl(item, chapter, index, maxWidth, apiClient) { + + if (chapter.ImageTag) { + + return apiClient.getScaledImageUrl(item.Id, { + maxWidth: maxWidth, + tag: chapter.ImageTag, + type: "Chapter", + index: index + }); + } + + return null; + } + + function renderScenePicker(progressPct) { + + chapterPcts = []; + var item = currentItem; + if (!item) { + return; + } + + var chapters = item.Chapters || []; + + var currentIndex = -1; + + var apiClient = connectionManager.getApiClient(item.ServerId); + + scenePicker.innerHTML = chapters.map(function (chapter) { + currentIndex++; + return getChapterHtml(item, chapter, currentIndex, 400, apiClient); + }).join(''); + + imageLoader.lazyChildren(scenePicker); + fadeIn(scenePicker, progressPct); + } + + var hideScenePickerTimeout; + var chapterPcts = []; + + function showScenePicker() { + + var progressPct = nowPlayingPositionSlider.value; + + if (!isScenePickerRendered) { + isScenePickerRendered = true; + renderScenePicker(); + } else { + fadeIn(scenePicker, progressPct); + } + + if (hideScenePickerTimeout) { + clearTimeout(hideScenePickerTimeout); + } + hideScenePickerTimeout = setTimeout(hideScenePicker, 1600); + } + + function hideScenePicker() { + fadeOut(scenePicker); + } + + var showScenePickerTimeout; + + function startScenePickerTimer() { + if (!showScenePickerTimeout) { + showScenePickerTimeout = setTimeout(showScenePicker, 100); + } + } + + function stopScenePickerTimer() { + if (showScenePickerTimeout) { + clearTimeout(showScenePickerTimeout); + showScenePickerTimeout = null; + } + } + + dom.addEventListener(nowPlayingPositionSlider, 'input', function () { + + if (scenePicker.classList.contains('hide')) { + startScenePickerTimer(); + } else { + showScenePicker(); + } + }, { + passive: true + }); + + function onViewHideStopPlayback() { + + if (playbackManager.isPlayingVideo()) { + + var player = currentPlayer; + + // Unbind this event so that we don't go back twice + view.removeEventListener('viewbeforehide', onViewHideStopPlayback); + + releaseCurrentPlayer(); + + playbackManager.stop(player); + + // or + //Emby.Page.setTransparency(Emby.TransparencyLevel.Backdrop); + } + } + + function fadeIn(elem, pct) { + + if (!elem.classList.contains('hide')) { + selectChapterThumb(elem, pct); + return; + } + + elem.classList.remove('hide'); + + var keyframes = [ + { opacity: '0', offset: 0 }, + { opacity: '1', offset: 1 } + ]; + var timing = { duration: 300, iterations: 1 }; + elem.animate(keyframes, timing).onfinish = function () { + selectChapterThumb(elem, pct); + }; + } + + function selectChapterThumb(elem, pct) { + var index = -1; + for (var i = 0, length = chapterPcts.length; i < length; i++) { + + if (pct >= chapterPcts[i]) { + index = i; + } + } + + if (index === -1) { + index = 0; + } + + var selected = elem.querySelector('.selectedChapterThumb'); + var newSelected = elem.querySelector('.chapterThumb[data-index="' + index + '"]'); + + if (selected !== newSelected) { + if (selected) { + selected.classList.remove('selectedChapterThumb'); + } + + newSelected.classList.add('selectedChapterThumb'); + scrollHelper.toCenter(elem, newSelected, true); + } + } + + function fadeOut(elem) { + + if (elem.classList.contains('hide')) { + return; + } + + var keyframes = [ + { opacity: '1', offset: 0 }, + { opacity: '0', offset: 1 } + ]; + var timing = { duration: 300, iterations: 1 }; + elem.animate(keyframes, timing).onfinish = function () { + elem.classList.add('hide'); + }; + } + + function enableStopOnBack(enabled) { + + view.removeEventListener('viewbeforehide', onViewHideStopPlayback); + + if (enabled) { + if (playbackManager.isPlayingVideo(currentPlayer)) { + view.addEventListener('viewbeforehide', onViewHideStopPlayback); + } + } + } + + }; + +}); \ No newline at end of file diff --git a/dashboard-ui/videoosd.html b/dashboard-ui/videoosd.html new file mode 100644 index 0000000000..a78bbf4140 --- /dev/null +++ b/dashboard-ui/videoosd.html @@ -0,0 +1,62 @@ +
+
+ +
+
+
+
+ +
+ +
+
+
+

+
+
+
+ +
+ +
+ + + + + + + + + + + + + +
+ +
+ +
+ +
+
+
+
+
+
\ No newline at end of file