diff --git a/package.json b/package.json index 0dad2dc99d..25e3d91e38 100644 --- a/package.json +++ b/package.json @@ -89,23 +89,31 @@ "overrides": [ { "test": [ + "src/components/actionSheet/actionSheet.js", "src/components/autoFocuser.js", "src/components/cardbuilder/cardBuilder.js", - "src/scripts/fileDownloader.js", "src/components/images/imageLoader.js", + "src/components/indicators/indicators.js", "src/components/lazyLoader/lazyLoaderIntersectionObserver.js", + "src/components/playback/brightnessosd.js", "src/components/playback/mediasession.js", + "src/components/playback/nowplayinghelper.js", + "src/components/playback/playbackorientation.js", + "src/components/playback/playerSelectionMenu.js", + "src/components/playback/playersettingsmenu.js", + "src/components/playback/playmethodhelper.js", + "src/components/playback/remotecontrolautoplay.js", + "src/components/playback/volumeosd.js", + "src/components/playmenu.js", "src/components/sanatizefilename.js", "src/components/scrollManager.js", + "src/scripts/deleteHelper.js", "src/scripts/dfnshelper.js", "src/scripts/dom.js", + "src/scripts/fileDownloader.js", "src/scripts/filesystem.js", "src/scripts/imagehelper.js", "src/scripts/inputManager.js", - "src/scripts/deleteHelper.js", - "src/components/actionSheet/actionSheet.js", - "src/components/playmenu.js", - "src/components/indicators/indicators.js", "src/scripts/keyboardNavigation.js", "src/scripts/settings/appSettings.js", "src/scripts/settings/userSettings.js", diff --git a/src/components/playback/brightnessosd.js b/src/components/playback/brightnessosd.js index 5ed2b8f81f..3a0e270257 100644 --- a/src/components/playback/brightnessosd.js +++ b/src/components/playback/brightnessosd.js @@ -1,171 +1,173 @@ -define(['events', 'playbackManager', 'dom', 'browser', 'css!./iconosd', 'material-icons'], function (events, playbackManager, dom, browser) { - 'use strict'; +import events from 'events'; +import playbackManager from 'playbackManager'; +import dom from 'dom'; +import browser from 'browser'; +import 'css!./iconosd'; +import 'material-icons'; - var currentPlayer; - var osdElement; - var iconElement; - var progressElement; +var currentPlayer; +var osdElement; +var iconElement; +var progressElement; - var enableAnimation; +var enableAnimation; - function getOsdElementHtml() { - var html = ''; +function getOsdElementHtml() { + var html = ''; - html += ''; + html += ''; - html += '
'; + html += '
'; - return html; + return html; +} + +function ensureOsdElement() { + + var elem = osdElement; + if (!elem) { + + enableAnimation = browser.supportsCssAnimation(); + + elem = document.createElement('div'); + elem.classList.add('hide'); + elem.classList.add('iconOsd'); + elem.classList.add('iconOsd-hidden'); + elem.classList.add('brightnessOsd'); + elem.innerHTML = getOsdElementHtml(); + + iconElement = elem.querySelector('.material-icons'); + progressElement = elem.querySelector('.iconOsdProgressInner'); + + document.body.appendChild(elem); + osdElement = elem; } +} - function ensureOsdElement() { +function onHideComplete() { + this.classList.add('hide'); +} - var elem = osdElement; - if (!elem) { +var hideTimeout; +function showOsd() { - enableAnimation = browser.supportsCssAnimation(); + clearHideTimeout(); - elem = document.createElement('div'); - elem.classList.add('hide'); - elem.classList.add('iconOsd'); - elem.classList.add('iconOsd-hidden'); - elem.classList.add('brightnessOsd'); - elem.innerHTML = getOsdElementHtml(); + var elem = osdElement; - iconElement = elem.querySelector('.material-icons'); - progressElement = elem.querySelector('.iconOsdProgressInner'); - - document.body.appendChild(elem); - osdElement = elem; - } - } - - function onHideComplete() { - this.classList.add('hide'); - } - - var hideTimeout; - function showOsd() { - - clearHideTimeout(); - - var elem = osdElement; - - dom.removeEventListener(elem, dom.whichTransitionEvent(), onHideComplete, { - once: true - }); - - elem.classList.remove('hide'); - - // trigger reflow - void elem.offsetWidth; - - requestAnimationFrame(function () { - elem.classList.remove('iconOsd-hidden'); - - hideTimeout = setTimeout(hideOsd, 3000); - }); - } - - function clearHideTimeout() { - if (hideTimeout) { - clearTimeout(hideTimeout); - hideTimeout = null; - } - } - - function hideOsd() { - - clearHideTimeout(); - - var elem = osdElement; - if (elem) { - - if (enableAnimation) { - // trigger reflow - void elem.offsetWidth; - - requestAnimationFrame(function () { - elem.classList.add('iconOsd-hidden'); - - dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, { - once: true - }); - }); - } else { - onHideComplete.call(elem); - } - } - } - - function setIcon(iconElement, icon) { - iconElement.classList.remove('brightness_high'); - iconElement.classList.remove('brightness_medium'); - iconElement.classList.remove('brightness_low'); - iconElement.classList.add(icon); - } - - function updateElementsFromPlayer(brightness) { - - if (iconElement) { - if (brightness >= 80) { - setIcon(iconElement, 'brightness_high'); - } else if (brightness >= 20) { - setIcon(iconElement, 'brightness_medium'); - } else { - setIcon(iconElement, 'brightness_low'); - } - } - if (progressElement) { - progressElement.style.width = (brightness || 0) + '%'; - } - } - - function releaseCurrentPlayer() { - - var player = currentPlayer; - - if (player) { - events.off(player, 'brightnesschange', onBrightnessChanged); - events.off(player, 'playbackstop', hideOsd); - currentPlayer = null; - } - } - - function onBrightnessChanged(e) { - - var player = this; - - ensureOsdElement(); - - updateElementsFromPlayer(playbackManager.getBrightness(player)); - - showOsd(); - } - - function bindToPlayer(player) { - - if (player === currentPlayer) { - return; - } - - releaseCurrentPlayer(); - - currentPlayer = player; - - if (!player) { - return; - } - - hideOsd(); - events.on(player, 'brightnesschange', onBrightnessChanged); - events.on(player, 'playbackstop', hideOsd); - } - - events.on(playbackManager, 'playerchange', function () { - bindToPlayer(playbackManager.getCurrentPlayer()); + dom.removeEventListener(elem, dom.whichTransitionEvent(), onHideComplete, { + once: true }); - bindToPlayer(playbackManager.getCurrentPlayer()); + elem.classList.remove('hide'); + // trigger reflow + void elem.offsetWidth; + + requestAnimationFrame(function () { + elem.classList.remove('iconOsd-hidden'); + + hideTimeout = setTimeout(hideOsd, 3000); + }); +} + +function clearHideTimeout() { + if (hideTimeout) { + clearTimeout(hideTimeout); + hideTimeout = null; + } +} + +function hideOsd() { + + clearHideTimeout(); + + var elem = osdElement; + if (elem) { + + if (enableAnimation) { + // trigger reflow + void elem.offsetWidth; + + requestAnimationFrame(function () { + elem.classList.add('iconOsd-hidden'); + + dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, { + once: true + }); + }); + } else { + onHideComplete.call(elem); + } + } +} + +function setIcon(iconElement, icon) { + iconElement.classList.remove('brightness_high'); + iconElement.classList.remove('brightness_medium'); + iconElement.classList.remove('brightness_low'); + iconElement.classList.add(icon); +} + +function updateElementsFromPlayer(brightness) { + + if (iconElement) { + if (brightness >= 80) { + setIcon(iconElement, 'brightness_high'); + } else if (brightness >= 20) { + setIcon(iconElement, 'brightness_medium'); + } else { + setIcon(iconElement, 'brightness_low'); + } + } + if (progressElement) { + progressElement.style.width = (brightness || 0) + '%'; + } +} + +function releaseCurrentPlayer() { + + var player = currentPlayer; + + if (player) { + events.off(player, 'brightnesschange', onBrightnessChanged); + events.off(player, 'playbackstop', hideOsd); + currentPlayer = null; + } +} + +function onBrightnessChanged(e) { + + var player = this; + + ensureOsdElement(); + + updateElementsFromPlayer(playbackManager.getBrightness(player)); + + showOsd(); +} + +function bindToPlayer(player) { + + if (player === currentPlayer) { + return; + } + + releaseCurrentPlayer(); + + currentPlayer = player; + + if (!player) { + return; + } + + hideOsd(); + events.on(player, 'brightnesschange', onBrightnessChanged); + events.on(player, 'playbackstop', hideOsd); +} + +events.on(playbackManager, 'playerchange', function () { + bindToPlayer(playbackManager.getCurrentPlayer()); }); + +bindToPlayer(playbackManager.getCurrentPlayer()); diff --git a/src/components/playback/nowplayinghelper.js b/src/components/playback/nowplayinghelper.js index 9bba23c294..310edc03c3 100644 --- a/src/components/playback/nowplayinghelper.js +++ b/src/components/playback/nowplayinghelper.js @@ -1,86 +1,82 @@ -define([], function () { - 'use strict'; +export function getNowPlayingNames(nowPlayingItem, includeNonNameInfo) { - function getNowPlayingNames(nowPlayingItem, includeNonNameInfo) { + var topItem = nowPlayingItem; + var bottomItem = null; + var topText = nowPlayingItem.Name; - var topItem = nowPlayingItem; - var bottomItem = null; - var topText = nowPlayingItem.Name; - - if (nowPlayingItem.AlbumId && nowPlayingItem.MediaType === 'Audio') { - topItem = { - Id: nowPlayingItem.AlbumId, - Name: nowPlayingItem.Album, - Type: 'MusicAlbum', - IsFolder: true - }; - } - - if (nowPlayingItem.MediaType === 'Video') { - if (nowPlayingItem.IndexNumber != null) { - topText = nowPlayingItem.IndexNumber + ' - ' + topText; - } - if (nowPlayingItem.ParentIndexNumber != null) { - topText = nowPlayingItem.ParentIndexNumber + '.' + topText; - } - } - - var bottomText = ''; - - if (nowPlayingItem.ArtistItems && nowPlayingItem.ArtistItems.length) { - - bottomItem = { - Id: nowPlayingItem.ArtistItems[0].Id, - Name: nowPlayingItem.ArtistItems[0].Name, - Type: 'MusicArtist', - IsFolder: true - }; - - bottomText = nowPlayingItem.ArtistItems.map(function (a) { - return a.Name; - }).join(', '); - - } else if (nowPlayingItem.Artists && nowPlayingItem.Artists.length) { - - bottomText = nowPlayingItem.Artists.join(', '); - } else if (nowPlayingItem.SeriesName || nowPlayingItem.Album) { - bottomText = topText; - topText = nowPlayingItem.SeriesName || nowPlayingItem.Album; - - bottomItem = topItem; - - if (nowPlayingItem.SeriesId) { - topItem = { - Id: nowPlayingItem.SeriesId, - Name: nowPlayingItem.SeriesName, - Type: 'Series', - IsFolder: true - }; - } else { - topItem = null; - } - } else if (nowPlayingItem.ProductionYear && includeNonNameInfo !== false) { - bottomText = nowPlayingItem.ProductionYear; - } - - var list = []; - - list.push({ - text: topText, - item: topItem - }); - - if (bottomText) { - list.push({ - text: bottomText, - item: bottomItem - }); - } - - return list; + if (nowPlayingItem.AlbumId && nowPlayingItem.MediaType === 'Audio') { + topItem = { + Id: nowPlayingItem.AlbumId, + Name: nowPlayingItem.Album, + Type: 'MusicAlbum', + IsFolder: true + }; } - return { - getNowPlayingNames: getNowPlayingNames - }; -}); + if (nowPlayingItem.MediaType === 'Video') { + if (nowPlayingItem.IndexNumber != null) { + topText = nowPlayingItem.IndexNumber + ' - ' + topText; + } + if (nowPlayingItem.ParentIndexNumber != null) { + topText = nowPlayingItem.ParentIndexNumber + '.' + topText; + } + } + + var bottomText = ''; + + if (nowPlayingItem.ArtistItems && nowPlayingItem.ArtistItems.length) { + + bottomItem = { + Id: nowPlayingItem.ArtistItems[0].Id, + Name: nowPlayingItem.ArtistItems[0].Name, + Type: 'MusicArtist', + IsFolder: true + }; + + bottomText = nowPlayingItem.ArtistItems.map(function (a) { + return a.Name; + }).join(', '); + + } else if (nowPlayingItem.Artists && nowPlayingItem.Artists.length) { + + bottomText = nowPlayingItem.Artists.join(', '); + } else if (nowPlayingItem.SeriesName || nowPlayingItem.Album) { + bottomText = topText; + topText = nowPlayingItem.SeriesName || nowPlayingItem.Album; + + bottomItem = topItem; + + if (nowPlayingItem.SeriesId) { + topItem = { + Id: nowPlayingItem.SeriesId, + Name: nowPlayingItem.SeriesName, + Type: 'Series', + IsFolder: true + }; + } else { + topItem = null; + } + } else if (nowPlayingItem.ProductionYear && includeNonNameInfo !== false) { + bottomText = nowPlayingItem.ProductionYear; + } + + var list = []; + + list.push({ + text: topText, + item: topItem + }); + + if (bottomText) { + list.push({ + text: bottomText, + item: bottomItem + }); + } + + return list; +} + +export default { + getNowPlayingNames: getNowPlayingNames +}; diff --git a/src/components/playback/playbackorientation.js b/src/components/playback/playbackorientation.js index 654ac29848..2078c6f6a8 100644 --- a/src/components/playback/playbackorientation.js +++ b/src/components/playback/playbackorientation.js @@ -1,57 +1,57 @@ -define(['playbackManager', 'layoutManager', 'events'], function (playbackManager, layoutManager, events) { - 'use strict'; +import playbackManager from 'playbackManager'; +import layoutManager from 'layoutManager'; +import events from 'events'; - var orientationLocked; +var orientationLocked; - function onOrientationChangeSuccess() { - orientationLocked = true; - } +function onOrientationChangeSuccess() { + orientationLocked = true; +} - function onOrientationChangeError(err) { - orientationLocked = false; - console.error('error locking orientation: ' + err); - } +function onOrientationChangeError(err) { + orientationLocked = false; + console.error('error locking orientation: ' + err); +} - events.on(playbackManager, 'playbackstart', function (e, player, state) { +events.on(playbackManager, 'playbackstart', function (e, player, state) { - var isLocalVideo = player.isLocalPlayer && !player.isExternalPlayer && playbackManager.isPlayingVideo(player); + var isLocalVideo = player.isLocalPlayer && !player.isExternalPlayer && playbackManager.isPlayingVideo(player); - if (isLocalVideo && layoutManager.mobile) { - /* eslint-disable-next-line compat/compat */ - var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation || (screen.orientation && screen.orientation.lock); + if (isLocalVideo && layoutManager.mobile) { + /* eslint-disable-next-line compat/compat */ + var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation || (screen.orientation && screen.orientation.lock); - if (lockOrientation) { + if (lockOrientation) { - try { - var promise = lockOrientation('landscape'); - if (promise.then) { - promise.then(onOrientationChangeSuccess, onOrientationChangeError); - } else { - // returns a boolean - orientationLocked = promise; - } - } catch (err) { - onOrientationChangeError(err); + try { + var promise = lockOrientation('landscape'); + if (promise.then) { + promise.then(onOrientationChangeSuccess, onOrientationChangeError); + } else { + // returns a boolean + orientationLocked = promise; } + } catch (err) { + onOrientationChangeError(err); } } - }); - - events.on(playbackManager, 'playbackstop', function (e, playbackStopInfo) { - - if (orientationLocked && !playbackStopInfo.nextMediaType) { - - /* eslint-disable-next-line compat/compat */ - var unlockOrientation = screen.unlockOrientation || screen.mozUnlockOrientation || screen.msUnlockOrientation || (screen.orientation && screen.orientation.unlock); - - if (unlockOrientation) { - try { - unlockOrientation(); - } catch (err) { - console.error('error unlocking orientation: ' + err); - } - orientationLocked = false; - } - } - }); + } +}); + +events.on(playbackManager, 'playbackstop', function (e, playbackStopInfo) { + + if (orientationLocked && !playbackStopInfo.nextMediaType) { + + /* eslint-disable-next-line compat/compat */ + var unlockOrientation = screen.unlockOrientation || screen.mozUnlockOrientation || screen.msUnlockOrientation || (screen.orientation && screen.orientation.unlock); + + if (unlockOrientation) { + try { + unlockOrientation(); + } catch (err) { + console.error('error unlocking orientation: ' + err); + } + orientationLocked = false; + } + } }); diff --git a/src/components/playback/playerSelectionMenu.js b/src/components/playback/playerSelectionMenu.js index 329cc11f92..eb0ae08497 100644 --- a/src/components/playback/playerSelectionMenu.js +++ b/src/components/playback/playerSelectionMenu.js @@ -1,320 +1,325 @@ -define(['appSettings', 'events', 'browser', 'loading', 'playbackManager', 'appRouter', 'globalize', 'apphost'], function (appSettings, events, browser, loading, playbackManager, appRouter, globalize, appHost) { - 'use strict'; +import appSettings from 'appSettings'; +import events from 'events'; +import browser from 'browser'; +import loading from 'loading'; +import playbackManager from 'playbackManager'; +import appRouter from 'appRouter'; +import globalize from 'globalize'; +import appHost from 'apphost'; - function mirrorItem(info, player) { +function mirrorItem(info, player) { - var item = info.item; + var item = info.item; - playbackManager.displayContent({ + playbackManager.displayContent({ - ItemName: item.Name, - ItemId: item.Id, - ItemType: item.Type, - Context: info.context - }, player); - } + ItemName: item.Name, + ItemId: item.Id, + ItemType: item.Type, + Context: info.context + }, player); +} - function mirrorIfEnabled(info) { +function mirrorIfEnabled(info) { - if (info && playbackManager.enableDisplayMirroring()) { + if (info && playbackManager.enableDisplayMirroring()) { - var getPlayerInfo = playbackManager.getPlayerInfo(); + var getPlayerInfo = playbackManager.getPlayerInfo(); - if (getPlayerInfo) { - if (!getPlayerInfo.isLocalPlayer && getPlayerInfo.supportedCommands.indexOf('DisplayContent') !== -1) { - mirrorItem(info, playbackManager.getCurrentPlayer()); - } + if (getPlayerInfo) { + if (!getPlayerInfo.isLocalPlayer && getPlayerInfo.supportedCommands.indexOf('DisplayContent') !== -1) { + mirrorItem(info, playbackManager.getCurrentPlayer()); } } } +} - function emptyCallback() { - // avoid console logs about uncaught promises +function emptyCallback() { + // avoid console logs about uncaught promises +} + +function getTargetSecondaryText(target) { + + if (target.user) { + + return target.user.Name; } - function getTargetSecondaryText(target) { + return null; +} - if (target.user) { +function getIcon(target) { - return target.user.Name; - } + var deviceType = target.deviceType; - return null; - } - - function getIcon(target) { - - var deviceType = target.deviceType; - - if (!deviceType && target.isLocalPlayer) { - if (browser.tv) { - deviceType = 'tv'; - } else if (browser.mobile) { - deviceType = 'smartphone'; - } else { - deviceType = 'desktop'; - } - } - - if (!deviceType) { + if (!deviceType && target.isLocalPlayer) { + if (browser.tv) { deviceType = 'tv'; - } - - switch (deviceType) { - - case 'smartphone': - return 'smartphone'; - case 'tablet': - return 'tablet'; - case 'tv': - return 'tv'; - case 'cast': - return 'cast'; - case 'desktop': - return 'computer'; - default: - return 'tv'; - } - } - - function showPlayerSelection(button) { - - var currentPlayerInfo = playbackManager.getPlayerInfo(); - - if (currentPlayerInfo) { - if (!currentPlayerInfo.isLocalPlayer) { - showActivePlayerMenu(currentPlayerInfo); - return; - } - } - - var currentPlayerId = currentPlayerInfo ? currentPlayerInfo.id : null; - - loading.show(); - - playbackManager.getTargets().then(function (targets) { - - var menuItems = targets.map(function (t) { - - var name = t.name; - - if (t.appName && t.appName !== t.name) { - name += ' - ' + t.appName; - } - - return { - name: name, - id: t.id, - selected: currentPlayerId === t.id, - secondaryText: getTargetSecondaryText(t), - icon: getIcon(t) - }; - - }); - - require(['actionsheet'], function (actionsheet) { - - loading.hide(); - - var menuOptions = { - title: globalize.translate('HeaderPlayOn'), - items: menuItems, - positionTo: button, - - resolveOnClick: true, - border: true - }; - - // Unfortunately we can't allow the url to change or chromecast will throw a security error - // Might be able to solve this in the future by moving the dialogs to hashbangs - if (!(!browser.chrome || appHost.supports('castmenuhashchange'))) { - menuOptions.enableHistory = false; - } - - actionsheet.show(menuOptions).then(function (id) { - - var target = targets.filter(function (t) { - return t.id === id; - })[0]; - - playbackManager.trySetActivePlayer(target.playerName, target); - - mirrorIfEnabled(); - - }, emptyCallback); - }); - }); - } - - function showActivePlayerMenu(playerInfo) { - - require(['dialogHelper', 'dialog', 'emby-checkbox', 'emby-button'], function (dialogHelper) { - showActivePlayerMenuInternal(dialogHelper, playerInfo); - }); - } - - function disconnectFromPlayer(currentDeviceName) { - - if (playbackManager.getSupportedCommands().indexOf('EndSession') !== -1) { - - require(['dialog'], function (dialog) { - - var menuItems = []; - - menuItems.push({ - name: globalize.translate('Yes'), - id: 'yes' - }); - menuItems.push({ - name: globalize.translate('No'), - id: 'no' - }); - - dialog({ - buttons: menuItems, - //positionTo: positionTo, - text: globalize.translate('ConfirmEndPlayerSession', currentDeviceName) - - }).then(function (id) { - switch (id) { - - case 'yes': - playbackManager.getCurrentPlayer().endSession(); - playbackManager.setDefaultPlayerActive(); - break; - case 'no': - playbackManager.setDefaultPlayerActive(); - break; - default: - break; - } - }); - - }); - + } else if (browser.mobile) { + deviceType = 'smartphone'; } else { - - playbackManager.setDefaultPlayerActive(); + deviceType = 'desktop'; } } - function showActivePlayerMenuInternal(dialogHelper, playerInfo) { - - var html = ''; - - var dialogOptions = { - removeOnClose: true - }; - - dialogOptions.modal = false; - dialogOptions.entryAnimationDuration = 160; - dialogOptions.exitAnimationDuration = 160; - dialogOptions.autoFocus = false; - - var dlg = dialogHelper.createDialog(dialogOptions); - - dlg.classList.add('promptDialog'); - - var currentDeviceName = (playerInfo.deviceName || playerInfo.name); - - html += '
'; - html += '

'; - html += currentDeviceName; - html += '

'; - - html += '
'; - - if (playerInfo.supportedCommands.indexOf('DisplayContent') !== -1) { - - html += ''; - } - - html += '
'; - - html += '
'; - - html += ''; - html += ''; - html += ''; - html += '
'; - - html += '
'; - dlg.innerHTML = html; - - var chkMirror = dlg.querySelector('.chkMirror'); - - if (chkMirror) { - chkMirror.addEventListener('change', onMirrorChange); - } - - var destination = ''; - - var btnRemoteControl = dlg.querySelector('.btnRemoteControl'); - if (btnRemoteControl) { - btnRemoteControl.addEventListener('click', function () { - destination = 'nowplaying'; - dialogHelper.close(dlg); - }); - } - - dlg.querySelector('.btnDisconnect').addEventListener('click', function () { - destination = 'disconnectFromPlayer'; - dialogHelper.close(dlg); - }); - - dlg.querySelector('.btnCancel').addEventListener('click', function () { - dialogHelper.close(dlg); - }); - - dialogHelper.open(dlg).then(function () { - if (destination === 'nowplaying') { - appRouter.showNowPlaying(); - } else if (destination === 'disconnectFromPlayer') { - disconnectFromPlayer(currentDeviceName); - } - }, emptyCallback); + if (!deviceType) { + deviceType = 'tv'; } - function onMirrorChange() { - playbackManager.enableDisplayMirroring(this.checked); + switch (deviceType) { + + case 'smartphone': + return 'smartphone'; + case 'tablet': + return 'tablet'; + case 'tv': + return 'tv'; + case 'cast': + return 'cast'; + case 'desktop': + return 'computer'; + default: + return 'tv'; } +} - document.addEventListener('viewshow', function (e) { +export function showPlayerSelection(button) { - var state = e.detail.state || {}; - var item = state.item; + var currentPlayerInfo = playbackManager.getPlayerInfo(); - if (item && item.ServerId) { - mirrorIfEnabled({ - item: item - }); + if (currentPlayerInfo) { + if (!currentPlayerInfo.isLocalPlayer) { + showActivePlayerMenu(currentPlayerInfo); return; } - }); + } - events.on(appSettings, 'change', function (e, name) { - if (name === 'displaymirror') { - mirrorIfEnabled(); - } - }); + var currentPlayerId = currentPlayerInfo ? currentPlayerInfo.id : null; - events.on(playbackManager, 'pairing', function (e) { - loading.show(); - }); + loading.show(); - events.on(playbackManager, 'paired', function (e) { - loading.hide(); - }); + playbackManager.getTargets().then(function (targets) { - events.on(playbackManager, 'pairerror', function (e) { - loading.hide(); - }); + var menuItems = targets.map(function (t) { - return { - show: showPlayerSelection + var name = t.name; + + if (t.appName && t.appName !== t.name) { + name += ' - ' + t.appName; + } + + return { + name: name, + id: t.id, + selected: currentPlayerId === t.id, + secondaryText: getTargetSecondaryText(t), + icon: getIcon(t) + }; + + }); + + require(['actionsheet'], function (actionsheet) { + + loading.hide(); + + var menuOptions = { + title: globalize.translate('HeaderPlayOn'), + items: menuItems, + positionTo: button, + + resolveOnClick: true, + border: true + }; + + // Unfortunately we can't allow the url to change or chromecast will throw a security error + // Might be able to solve this in the future by moving the dialogs to hashbangs + if (!(!browser.chrome || appHost.supports('castmenuhashchange'))) { + menuOptions.enableHistory = false; + } + + actionsheet.show(menuOptions).then(function (id) { + + var target = targets.filter(function (t) { + return t.id === id; + })[0]; + + playbackManager.trySetActivePlayer(target.playerName, target); + + mirrorIfEnabled(); + + }, emptyCallback); + }); + }); +} + +function showActivePlayerMenu(playerInfo) { + + require(['dialogHelper', 'dialog', 'emby-checkbox', 'emby-button'], function (dialogHelper) { + showActivePlayerMenuInternal(dialogHelper, playerInfo); + }); +} + +function disconnectFromPlayer(currentDeviceName) { + + if (playbackManager.getSupportedCommands().indexOf('EndSession') !== -1) { + + require(['dialog'], function (dialog) { + + var menuItems = []; + + menuItems.push({ + name: globalize.translate('Yes'), + id: 'yes' + }); + menuItems.push({ + name: globalize.translate('No'), + id: 'no' + }); + + dialog({ + buttons: menuItems, + //positionTo: positionTo, + text: globalize.translate('ConfirmEndPlayerSession', currentDeviceName) + + }).then(function (id) { + switch (id) { + + case 'yes': + playbackManager.getCurrentPlayer().endSession(); + playbackManager.setDefaultPlayerActive(); + break; + case 'no': + playbackManager.setDefaultPlayerActive(); + break; + default: + break; + } + }); + + }); + + } else { + + playbackManager.setDefaultPlayerActive(); + } +} + +function showActivePlayerMenuInternal(dialogHelper, playerInfo) { + + var html = ''; + + var dialogOptions = { + removeOnClose: true }; + + dialogOptions.modal = false; + dialogOptions.entryAnimationDuration = 160; + dialogOptions.exitAnimationDuration = 160; + dialogOptions.autoFocus = false; + + var dlg = dialogHelper.createDialog(dialogOptions); + + dlg.classList.add('promptDialog'); + + var currentDeviceName = (playerInfo.deviceName || playerInfo.name); + + html += '
'; + html += '

'; + html += currentDeviceName; + html += '

'; + + html += '
'; + + if (playerInfo.supportedCommands.indexOf('DisplayContent') !== -1) { + + html += ''; + } + + html += '
'; + + html += '
'; + + html += ''; + html += ''; + html += ''; + html += '
'; + + html += '
'; + dlg.innerHTML = html; + + var chkMirror = dlg.querySelector('.chkMirror'); + + if (chkMirror) { + chkMirror.addEventListener('change', onMirrorChange); + } + + var destination = ''; + + var btnRemoteControl = dlg.querySelector('.btnRemoteControl'); + if (btnRemoteControl) { + btnRemoteControl.addEventListener('click', function () { + destination = 'nowplaying'; + dialogHelper.close(dlg); + }); + } + + dlg.querySelector('.btnDisconnect').addEventListener('click', function () { + destination = 'disconnectFromPlayer'; + dialogHelper.close(dlg); + }); + + dlg.querySelector('.btnCancel').addEventListener('click', function () { + dialogHelper.close(dlg); + }); + + dialogHelper.open(dlg).then(function () { + if (destination === 'nowplaying') { + appRouter.showNowPlaying(); + } else if (destination === 'disconnectFromPlayer') { + disconnectFromPlayer(currentDeviceName); + } + }, emptyCallback); +} + +function onMirrorChange() { + playbackManager.enableDisplayMirroring(this.checked); +} + +document.addEventListener('viewshow', function (e) { + + var state = e.detail.state || {}; + var item = state.item; + + if (item && item.ServerId) { + mirrorIfEnabled({ + item: item + }); + return; + } }); + +events.on(appSettings, 'change', function (e, name) { + if (name === 'displaymirror') { + mirrorIfEnabled(); + } +}); + +events.on(playbackManager, 'pairing', function (e) { + loading.show(); +}); + +events.on(playbackManager, 'paired', function (e) { + loading.hide(); +}); + +events.on(playbackManager, 'pairerror', function (e) { + loading.hide(); +}); + +export default { + show: showPlayerSelection +}; diff --git a/src/components/playback/playersettingsmenu.js b/src/components/playback/playersettingsmenu.js index dd67b667e6..2544590b34 100644 --- a/src/components/playback/playersettingsmenu.js +++ b/src/components/playback/playersettingsmenu.js @@ -1,270 +1,274 @@ -define(['connectionManager', 'actionsheet', 'datetime', 'playbackManager', 'globalize', 'appSettings', 'qualityoptions'], function (connectionManager, actionsheet, datetime, playbackManager, globalize, appSettings, qualityoptions) { - 'use strict'; +import connectionManager from 'connectionManager'; +import actionsheet from 'actionsheet'; +import datetime from 'datetime'; +import playbackManager from 'playbackManager'; +import globalize from 'globalize'; +import appSettings from 'appSettings'; +import qualityoptions from 'qualityoptions'; - function showQualityMenu(player, btn) { +function showQualityMenu(player, btn) { - var videoStream = playbackManager.currentMediaSource(player).MediaStreams.filter(function (stream) { - return stream.Type === 'Video'; - })[0]; - var videoWidth = videoStream ? videoStream.Width : null; - var videoHeight = videoStream ? videoStream.Height : null; + var videoStream = playbackManager.currentMediaSource(player).MediaStreams.filter(function (stream) { + return stream.Type === 'Video'; + })[0]; + var videoWidth = videoStream ? videoStream.Width : null; + var videoHeight = videoStream ? videoStream.Height : null; - var options = qualityoptions.getVideoQualityOptions({ - currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player), - isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player), - videoWidth: videoWidth, - videoHeight: videoHeight, - enableAuto: true - }); + var options = qualityoptions.getVideoQualityOptions({ + currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player), + isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player), + videoWidth: videoWidth, + videoHeight: videoHeight, + enableAuto: true + }); - var menuItems = options.map(function (o) { - var opt = { - name: o.name, - id: o.bitrate, - asideText: o.secondaryText - }; + var menuItems = options.map(function (o) { + var opt = { + name: o.name, + id: o.bitrate, + asideText: o.secondaryText + }; - if (o.selected) { - opt.selected = true; - } + if (o.selected) { + opt.selected = true; + } - return opt; - }); + return opt; + }); - var selectedId = options.filter(function (o) { - return o.selected; - }); + var selectedId = options.filter(function (o) { + return o.selected; + }); - selectedId = selectedId.length ? selectedId[0].bitrate : null; + selectedId = selectedId.length ? selectedId[0].bitrate : null; - return actionsheet.show({ - items: menuItems, - positionTo: btn - }).then(function (id) { - var bitrate = parseInt(id); - if (bitrate !== selectedId) { - playbackManager.setMaxStreamingBitrate({ - enableAutomaticBitrateDetection: bitrate ? false : true, - maxBitrate: bitrate - }, player); - } - }); + return actionsheet.show({ + items: menuItems, + positionTo: btn + }).then(function (id) { + var bitrate = parseInt(id); + if (bitrate !== selectedId) { + playbackManager.setMaxStreamingBitrate({ + enableAutomaticBitrateDetection: bitrate ? false : true, + maxBitrate: bitrate + }, player); + } + }); +} + +function showRepeatModeMenu(player, btn) { + var menuItems = []; + var currentValue = playbackManager.getRepeatMode(player); + + menuItems.push({ + name: globalize.translate('RepeatAll'), + id: 'RepeatAll', + selected: currentValue === 'RepeatAll' + }); + + menuItems.push({ + name: globalize.translate('RepeatOne'), + id: 'RepeatOne', + selected: currentValue === 'RepeatOne' + }); + + menuItems.push({ + name: globalize.translate('None'), + id: 'RepeatNone', + selected: currentValue === 'RepeatNone' + }); + + return actionsheet.show({ + items: menuItems, + positionTo: btn + }).then(function (mode) { + if (mode) { + playbackManager.setRepeatMode(mode, player); + } + }); +} + +function getQualitySecondaryText(player) { + var state = playbackManager.getPlayerState(player); + var isAutoEnabled = playbackManager.enableAutomaticBitrateDetection(player); + var currentMaxBitrate = playbackManager.getMaxStreamingBitrate(player); + + var videoStream = playbackManager.currentMediaSource(player).MediaStreams.filter(function (stream) { + return stream.Type === 'Video'; + })[0]; + + var videoWidth = videoStream ? videoStream.Width : null; + var videoHeight = videoStream ? videoStream.Height : null; + + var options = qualityoptions.getVideoQualityOptions({ + currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player), + isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player), + videoWidth: videoWidth, + videoHeight: videoHeight, + enableAuto: true + }); + + var menuItems = options.map(function (o) { + var opt = { + name: o.name, + id: o.bitrate, + asideText: o.secondaryText + }; + + if (o.selected) { + opt.selected = true; + } + + return opt; + }); + + var selectedOption = options.filter(function (o) { + return o.selected; + }); + + if (!selectedOption.length) { + return null; } - function showRepeatModeMenu(player, btn) { - var menuItems = []; - var currentValue = playbackManager.getRepeatMode(player); + selectedOption = selectedOption[0]; + var text = selectedOption.name; - menuItems.push({ - name: globalize.translate('RepeatAll'), - id: 'RepeatAll', - selected: currentValue === 'RepeatAll' - }); - - menuItems.push({ - name: globalize.translate('RepeatOne'), - id: 'RepeatOne', - selected: currentValue === 'RepeatOne' - }); - - menuItems.push({ - name: globalize.translate('None'), - id: 'RepeatNone', - selected: currentValue === 'RepeatNone' - }); - - return actionsheet.show({ - items: menuItems, - positionTo: btn - }).then(function (mode) { - if (mode) { - playbackManager.setRepeatMode(mode, player); - } - }); + if (selectedOption.autoText) { + if (state.PlayState && state.PlayState.PlayMethod !== 'Transcode') { + text += ' - Direct'; + } else { + text += ' ' + selectedOption.autoText; + } } - function getQualitySecondaryText(player) { - var state = playbackManager.getPlayerState(player); - var isAutoEnabled = playbackManager.enableAutomaticBitrateDetection(player); - var currentMaxBitrate = playbackManager.getMaxStreamingBitrate(player); + return text; +} - var videoStream = playbackManager.currentMediaSource(player).MediaStreams.filter(function (stream) { - return stream.Type === 'Video'; - })[0]; +function showAspectRatioMenu(player, btn) { + // each has a name and id + var currentId = playbackManager.getAspectRatio(player); + var menuItems = playbackManager.getSupportedAspectRatios(player).map(function (i) { + return { + id: i.id, + name: i.name, + selected: i.id === currentId + }; + }); - var videoWidth = videoStream ? videoStream.Width : null; - var videoHeight = videoStream ? videoStream.Height : null; - - var options = qualityoptions.getVideoQualityOptions({ - currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player), - isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player), - videoWidth: videoWidth, - videoHeight: videoHeight, - enableAuto: true - }); - - var menuItems = options.map(function (o) { - var opt = { - name: o.name, - id: o.bitrate, - asideText: o.secondaryText - }; - - if (o.selected) { - opt.selected = true; - } - - return opt; - }); - - var selectedOption = options.filter(function (o) { - return o.selected; - }); - - if (!selectedOption.length) { - return null; - } - - selectedOption = selectedOption[0]; - var text = selectedOption.name; - - if (selectedOption.autoText) { - if (state.PlayState && state.PlayState.PlayMethod !== 'Transcode') { - text += ' - Direct'; - } else { - text += ' ' + selectedOption.autoText; - } - } - - return text; - } - - function showAspectRatioMenu(player, btn) { - // each has a name and id - var currentId = playbackManager.getAspectRatio(player); - var menuItems = playbackManager.getSupportedAspectRatios(player).map(function (i) { - return { - id: i.id, - name: i.name, - selected: i.id === currentId - }; - }); - - return actionsheet.show({ - items: menuItems, - positionTo: btn - }).then(function (id) { - if (id) { - playbackManager.setAspectRatio(id, player); - return Promise.resolve(); - } - - return Promise.reject(); - }); - } - - function showWithUser(options, player, user) { - var supportedCommands = playbackManager.getSupportedCommands(player); - var mediaType = options.mediaType; - - var menuItems = []; - if (supportedCommands.indexOf('SetAspectRatio') !== -1) { - var currentAspectRatioId = playbackManager.getAspectRatio(player); - var currentAspectRatio = playbackManager.getSupportedAspectRatios(player).filter(function (i) { - return i.id === currentAspectRatioId; - })[0]; - - menuItems.push({ - name: globalize.translate('AspectRatio'), - id: 'aspectratio', - asideText: currentAspectRatio ? currentAspectRatio.name : null - }); - } - - if (user && user.Policy.EnableVideoPlaybackTranscoding) { - var secondaryQualityText = getQualitySecondaryText(player); - - menuItems.push({ - name: globalize.translate('Quality'), - id: 'quality', - asideText: secondaryQualityText - }); - } - - var repeatMode = playbackManager.getRepeatMode(player); - - if (supportedCommands.indexOf('SetRepeatMode') !== -1 && playbackManager.currentMediaSource(player).RunTimeTicks) { - menuItems.push({ - name: globalize.translate('RepeatMode'), - id: 'repeatmode', - asideText: repeatMode === 'RepeatNone' ? globalize.translate('None') : globalize.translate('' + repeatMode) - }); - } - - if (options.suboffset) { - menuItems.push({ - name: globalize.translate('SubtitleOffset'), - id: 'suboffset', - asideText: null - }); - } - - if (options.stats) { - menuItems.push({ - name: globalize.translate('PlaybackData'), - id: 'stats', - asideText: null - }); - } - - return actionsheet.show({ - items: menuItems, - positionTo: options.positionTo - }).then(function (id) { - return handleSelectedOption(id, options, player); - }); - } - - function show(options) { - var player = options.player; - var currentItem = playbackManager.currentItem(player); - - if (!currentItem || !currentItem.ServerId) { - return showWithUser(options, player, null); - } - - var apiClient = connectionManager.getApiClient(currentItem.ServerId); - return apiClient.getCurrentUser().then(function (user) { - return showWithUser(options, player, user); - }); - } - - function handleSelectedOption(id, options, player) { - switch (id) { - case 'quality': - return showQualityMenu(player, options.positionTo); - case 'aspectratio': - return showAspectRatioMenu(player, options.positionTo); - case 'repeatmode': - return showRepeatModeMenu(player, options.positionTo); - case 'stats': - if (options.onOption) { - options.onOption('stats'); - } - return Promise.resolve(); - case 'suboffset': - if (options.onOption) { - options.onOption('suboffset'); - } - return Promise.resolve(); - default: - break; + return actionsheet.show({ + items: menuItems, + positionTo: btn + }).then(function (id) { + if (id) { + playbackManager.setAspectRatio(id, player); + return Promise.resolve(); } return Promise.reject(); + }); +} + +function showWithUser(options, player, user) { + var supportedCommands = playbackManager.getSupportedCommands(player); + var mediaType = options.mediaType; + + var menuItems = []; + if (supportedCommands.indexOf('SetAspectRatio') !== -1) { + var currentAspectRatioId = playbackManager.getAspectRatio(player); + var currentAspectRatio = playbackManager.getSupportedAspectRatios(player).filter(function (i) { + return i.id === currentAspectRatioId; + })[0]; + + menuItems.push({ + name: globalize.translate('AspectRatio'), + id: 'aspectratio', + asideText: currentAspectRatio ? currentAspectRatio.name : null + }); } - return { - show: show - }; -}); + if (user && user.Policy.EnableVideoPlaybackTranscoding) { + var secondaryQualityText = getQualitySecondaryText(player); + + menuItems.push({ + name: globalize.translate('Quality'), + id: 'quality', + asideText: secondaryQualityText + }); + } + + var repeatMode = playbackManager.getRepeatMode(player); + + if (supportedCommands.indexOf('SetRepeatMode') !== -1 && playbackManager.currentMediaSource(player).RunTimeTicks) { + menuItems.push({ + name: globalize.translate('RepeatMode'), + id: 'repeatmode', + asideText: repeatMode === 'RepeatNone' ? globalize.translate('None') : globalize.translate('' + repeatMode) + }); + } + + if (options.suboffset) { + menuItems.push({ + name: globalize.translate('SubtitleOffset'), + id: 'suboffset', + asideText: null + }); + } + + if (options.stats) { + menuItems.push({ + name: globalize.translate('PlaybackData'), + id: 'stats', + asideText: null + }); + } + + return actionsheet.show({ + items: menuItems, + positionTo: options.positionTo + }).then(function (id) { + return handleSelectedOption(id, options, player); + }); +} + +export function show(options) { + var player = options.player; + var currentItem = playbackManager.currentItem(player); + + if (!currentItem || !currentItem.ServerId) { + return showWithUser(options, player, null); + } + + var apiClient = connectionManager.getApiClient(currentItem.ServerId); + return apiClient.getCurrentUser().then(function (user) { + return showWithUser(options, player, user); + }); +} + +function handleSelectedOption(id, options, player) { + switch (id) { + case 'quality': + return showQualityMenu(player, options.positionTo); + case 'aspectratio': + return showAspectRatioMenu(player, options.positionTo); + case 'repeatmode': + return showRepeatModeMenu(player, options.positionTo); + case 'stats': + if (options.onOption) { + options.onOption('stats'); + } + return Promise.resolve(); + case 'suboffset': + if (options.onOption) { + options.onOption('suboffset'); + } + return Promise.resolve(); + default: + break; + } + + return Promise.reject(); +} + +export default { + show: show +}; diff --git a/src/components/playback/playmethodhelper.js b/src/components/playback/playmethodhelper.js index 75af04035c..62793b9a33 100644 --- a/src/components/playback/playmethodhelper.js +++ b/src/components/playback/playmethodhelper.js @@ -1,24 +1,20 @@ -define([], function () { - 'use strict'; +export function getDisplayPlayMethod(session) { - function getDisplayPlayMethod(session) { - - if (!session.NowPlayingItem) { - return null; - } - - if (session.TranscodingInfo && session.TranscodingInfo.IsVideoDirect) { - return 'DirectStream'; - } else if (session.PlayState.PlayMethod === 'Transcode') { - return 'Transcode'; - } else if (session.PlayState.PlayMethod === 'DirectStream') { - return 'DirectPlay'; - } else if (session.PlayState.PlayMethod === 'DirectPlay') { - return 'DirectPlay'; - } + if (!session.NowPlayingItem) { + return null; } - return { - getDisplayPlayMethod: getDisplayPlayMethod - }; -}); + if (session.TranscodingInfo && session.TranscodingInfo.IsVideoDirect) { + return 'DirectStream'; + } else if (session.PlayState.PlayMethod === 'Transcode') { + return 'Transcode'; + } else if (session.PlayState.PlayMethod === 'DirectStream') { + return 'DirectPlay'; + } else if (session.PlayState.PlayMethod === 'DirectPlay') { + return 'DirectPlay'; + } +} + +export default { + getDisplayPlayMethod: getDisplayPlayMethod +}; diff --git a/src/components/playback/remotecontrolautoplay.js b/src/components/playback/remotecontrolautoplay.js index 90a872cc6e..b7da635cb7 100644 --- a/src/components/playback/remotecontrolautoplay.js +++ b/src/components/playback/remotecontrolautoplay.js @@ -1,47 +1,45 @@ -define(['events', 'playbackManager'], function (events, playbackManager) { - 'use strict'; +import events from 'events'; +import playbackManager from 'playbackManager'; - function transferPlayback(oldPlayer, newPlayer) { +function transferPlayback(oldPlayer, newPlayer) { - var state = playbackManager.getPlayerState(oldPlayer); + var state = playbackManager.getPlayerState(oldPlayer); - var item = state.NowPlayingItem; + var item = state.NowPlayingItem; - if (!item) { - return; - } - - var playState = state.PlayState || {}; - var resumePositionTicks = playState.PositionTicks || 0; - - playbackManager.stop(oldPlayer).then(function () { - - playbackManager.play({ - ids: [item.Id], - serverId: item.ServerId, - startPositionTicks: resumePositionTicks - - }, newPlayer); - }); + if (!item) { + return; } - events.on(playbackManager, 'playerchange', function (e, newPlayer, newTarget, oldPlayer) { + var playState = state.PlayState || {}; + var resumePositionTicks = playState.PositionTicks || 0; - if (!oldPlayer || !newPlayer) { - return; - } + playbackManager.stop(oldPlayer).then(function () { - if (!oldPlayer.isLocalPlayer) { - console.debug('Skipping remote control autoplay because oldPlayer is not a local player'); - return; - } + playbackManager.play({ + ids: [item.Id], + serverId: item.ServerId, + startPositionTicks: resumePositionTicks - if (newPlayer.isLocalPlayer) { - console.debug('Skipping remote control autoplay because newPlayer is a local player'); - return; - } - - transferPlayback(oldPlayer, newPlayer); + }, newPlayer); }); +} +events.on(playbackManager, 'playerchange', function (e, newPlayer, newTarget, oldPlayer) { + + if (!oldPlayer || !newPlayer) { + return; + } + + if (!oldPlayer.isLocalPlayer) { + console.debug('Skipping remote control autoplay because oldPlayer is not a local player'); + return; + } + + if (newPlayer.isLocalPlayer) { + console.debug('Skipping remote control autoplay because newPlayer is a local player'); + return; + } + + transferPlayback(oldPlayer, newPlayer); }); diff --git a/src/components/playback/volumeosd.js b/src/components/playback/volumeosd.js index 95a13d769d..c2f6761f53 100644 --- a/src/components/playback/volumeosd.js +++ b/src/components/playback/volumeosd.js @@ -1,159 +1,161 @@ -define(['events', 'playbackManager', 'dom', 'browser', 'css!./iconosd', 'material-icons'], function (events, playbackManager, dom, browser) { - 'use strict'; +import events from 'events'; +import playbackManager from 'playbackManager'; +import dom from 'dom'; +import browser from 'browser'; +import 'css!./iconosd'; +import 'material-icons'; - var currentPlayer; - var osdElement; - var iconElement; - var progressElement; +var currentPlayer; +var osdElement; +var iconElement; +var progressElement; - var enableAnimation; +var enableAnimation; - function getOsdElementHtml() { - var html = ''; +function getOsdElementHtml() { + var html = ''; - html += ''; + html += ''; - html += '
'; + html += '
'; - return html; + return html; +} + +function ensureOsdElement() { + + var elem = osdElement; + if (!elem) { + + enableAnimation = browser.supportsCssAnimation(); + + elem = document.createElement('div'); + elem.classList.add('hide'); + elem.classList.add('iconOsd'); + elem.classList.add('iconOsd-hidden'); + elem.classList.add('volumeOsd'); + elem.innerHTML = getOsdElementHtml(); + + iconElement = elem.querySelector('.material-icons'); + progressElement = elem.querySelector('.iconOsdProgressInner'); + + document.body.appendChild(elem); + osdElement = elem; } +} - function ensureOsdElement() { +function onHideComplete() { + this.classList.add('hide'); +} - var elem = osdElement; - if (!elem) { +var hideTimeout; +function showOsd() { - enableAnimation = browser.supportsCssAnimation(); + clearHideTimeout(); - elem = document.createElement('div'); - elem.classList.add('hide'); - elem.classList.add('iconOsd'); - elem.classList.add('iconOsd-hidden'); - elem.classList.add('volumeOsd'); - elem.innerHTML = getOsdElementHtml(); + var elem = osdElement; - iconElement = elem.querySelector('.material-icons'); - progressElement = elem.querySelector('.iconOsdProgressInner'); - - document.body.appendChild(elem); - osdElement = elem; - } - } - - function onHideComplete() { - this.classList.add('hide'); - } - - var hideTimeout; - function showOsd() { - - clearHideTimeout(); - - var elem = osdElement; - - dom.removeEventListener(elem, dom.whichTransitionEvent(), onHideComplete, { - once: true - }); - - elem.classList.remove('hide'); - - // trigger reflow - void elem.offsetWidth; - - requestAnimationFrame(function () { - elem.classList.remove('iconOsd-hidden'); - - hideTimeout = setTimeout(hideOsd, 3000); - }); - } - - function clearHideTimeout() { - if (hideTimeout) { - clearTimeout(hideTimeout); - hideTimeout = null; - } - } - - function hideOsd() { - - clearHideTimeout(); - - var elem = osdElement; - if (elem) { - - if (enableAnimation) { - // trigger reflow - void elem.offsetWidth; - - requestAnimationFrame(function () { - elem.classList.add('iconOsd-hidden'); - - dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, { - once: true - }); - }); - } else { - onHideComplete.call(elem); - } - } - } - - function updatePlayerVolumeState(isMuted, volume) { - - if (iconElement) { - iconElement.classList.remove('volume_off', 'volume_up'); - iconElement.classList.add(isMuted ? 'volume_off' : 'volume_up'); - } - if (progressElement) { - progressElement.style.width = (volume || 0) + '%'; - } - } - - function releaseCurrentPlayer() { - - var player = currentPlayer; - - if (player) { - events.off(player, 'volumechange', onVolumeChanged); - events.off(player, 'playbackstop', hideOsd); - currentPlayer = null; - } - } - - function onVolumeChanged(e) { - - var player = this; - - ensureOsdElement(); - - updatePlayerVolumeState(player.isMuted(), player.getVolume()); - - showOsd(); - } - - function bindToPlayer(player) { - - if (player === currentPlayer) { - return; - } - - releaseCurrentPlayer(); - - currentPlayer = player; - - if (!player) { - return; - } - - hideOsd(); - events.on(player, 'volumechange', onVolumeChanged); - events.on(player, 'playbackstop', hideOsd); - } - - events.on(playbackManager, 'playerchange', function () { - bindToPlayer(playbackManager.getCurrentPlayer()); + dom.removeEventListener(elem, dom.whichTransitionEvent(), onHideComplete, { + once: true }); - bindToPlayer(playbackManager.getCurrentPlayer()); + elem.classList.remove('hide'); + // trigger reflow + void elem.offsetWidth; + + requestAnimationFrame(function () { + elem.classList.remove('iconOsd-hidden'); + + hideTimeout = setTimeout(hideOsd, 3000); + }); +} + +function clearHideTimeout() { + if (hideTimeout) { + clearTimeout(hideTimeout); + hideTimeout = null; + } +} + +function hideOsd() { + + clearHideTimeout(); + + var elem = osdElement; + if (elem) { + + if (enableAnimation) { + // trigger reflow + void elem.offsetWidth; + + requestAnimationFrame(function () { + elem.classList.add('iconOsd-hidden'); + + dom.addEventListener(elem, dom.whichTransitionEvent(), onHideComplete, { + once: true + }); + }); + } else { + onHideComplete.call(elem); + } + } +} + +function updatePlayerVolumeState(isMuted, volume) { + + if (iconElement) { + iconElement.classList.remove('volume_off', 'volume_up'); + iconElement.classList.add(isMuted ? 'volume_off' : 'volume_up'); + } + if (progressElement) { + progressElement.style.width = (volume || 0) + '%'; + } +} + +function releaseCurrentPlayer() { + + var player = currentPlayer; + + if (player) { + events.off(player, 'volumechange', onVolumeChanged); + events.off(player, 'playbackstop', hideOsd); + currentPlayer = null; + } +} + +function onVolumeChanged(e) { + + var player = this; + + ensureOsdElement(); + + updatePlayerVolumeState(player.isMuted(), player.getVolume()); + + showOsd(); +} + +function bindToPlayer(player) { + + if (player === currentPlayer) { + return; + } + + releaseCurrentPlayer(); + + currentPlayer = player; + + if (!player) { + return; + } + + hideOsd(); + events.on(player, 'volumechange', onVolumeChanged); + events.on(player, 'playbackstop', hideOsd); +} + +events.on(playbackManager, 'playerchange', function () { + bindToPlayer(playbackManager.getCurrentPlayer()); }); + +bindToPlayer(playbackManager.getCurrentPlayer());