diff --git a/dashboard-ui/components/remotecontrol.js b/dashboard-ui/components/remotecontrol.js new file mode 100644 index 0000000000..323f625858 --- /dev/null +++ b/dashboard-ui/components/remotecontrol.js @@ -0,0 +1,1075 @@ +define(['browser', 'paper-fab', 'paper-tabs', 'paper-slider', 'paper-icon-button'], function (browser) { + + function getAnimatedPagesHtml() { + + var html = ''; + + html += '
\ +
\ +
\ +
\ + \ +
\ +
\ + \ + \ + \ + \ + \ +
\ +
\ + \ + \ + \ + \ +
\ + \ +
\ + \ + \ + \ + \ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ + \ +
\ +
\ + \ + \ + \ +
\ +
\ + \ +
\ +
\ + \ + \ +
\ +
\ +
\ + \ + \ + \ +
\ +
\ + \ + \ + \ +
\ +
\ +
\ +
\ +

${HeaderSendMessage}

\ +
\ +
\ +
\ + \ +
\ +
\ +
\ + \ +
\ +

\ + \ +

\ +
\ +
\ +
\ +
\ +

${HeaderTypeText}

\ +
\ +
\ +
\ + \ +
\ +

\ + \ +

\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +'; + + return html; + } + + function getHeaderHtml() { + + var html = ''; + + var position = AppInfo.enableNowPlayingPageBottomTabs ? 'absolute' : 'relative;'; + + html += '
'; + html += ''; + + html += '
'; + html += ''; + html += ''; + //html += ''; + html += '
'; + html += '
'; + + html += '
\ +
\ + ${TabNowPlaying}\ + ${TabControls}\ + ${TabPlaylist}\ +
\ +
\ + '; + + return html; + } + + function getTabsHtml() { + + var html = ''; + + html += '\ + ${TabNowPlaying}\ + ${TabControls}\ + ${TabPlaylist}\ + '; + + return html; + } + + function showSlideshowMenu(context) { + require(['scripts/slideshow'], function () { + SlideShow.showMenu(); + }); + } + + function showAudioMenu(context, player, button, item, currentIndex) { + + var streams = (item.MediaStreams || []).filter(function (i) { + + return i.Type == 'Audio'; + }); + + var menuItems = streams.map(function (s) { + + var name = (s.Codec || '').toUpperCase(); + + if (s.Profile) { + name += ' ' + s.Profile; + } + + if (s.Language) { + name += ' · ' + s.Language; + } + if (s.Layout) { + name += ' · ' + s.Layout; + } + else if (s.Channels) { + name += ' · ' + s.Channels + ' ch'; + } + + var menuItem = { + name: name, + id: s.Index + }; + + if (s.Index == currentIndex) { + menuItem.ironIcon = 'check'; + } + + return menuItem; + }); + + require(['actionsheet'], function (actionsheet) { + + actionsheet.show({ + items: menuItems, + positionTo: button, + callback: function (id) { + + player.setAudioStreamIndex(parseInt(id)); + } + }); + + }); + } + + function showSubtitleMenu(context, player, button, item, currentIndex) { + + var streams = (item.MediaStreams || []).filter(function (i) { + + return i.Type == 'Subtitle'; + }); + + var menuItems = streams.map(function (s) { + + var name = (s.Language || Globalize.translate('LabelUnknownLanguage')); + + if (s.IsDefault && s.IsForced) { + name += ' · ' + Globalize.translate('LabelDefaultForcedStream'); + } + else if (s.IsDefault) { + name += ' · ' + Globalize.translate('LabelDefaultStream'); + } + else if (s.IsForced) { + name += ' · ' + Globalize.translate('LabelForcedStream'); + } + + if (s.Codec) { + name += ' · ' + s.Codec.toUpperCase(); + } + + var menuItem = { + name: name, + id: s.Index + }; + + if (s.Index == currentIndex) { + menuItem.ironIcon = 'check'; + } + + return menuItem; + }); + + menuItems.unshift({ + id: -1, + name: Globalize.translate('ButtonOff'), + ironIcon: currentIndex == null ? 'check' : null + }); + + require(['actionsheet'], function (actionsheet) { + + actionsheet.show({ + items: menuItems, + positionTo: button, + callback: function (id) { + + player.setSubtitleStreamIndex(parseInt(id)); + } + }); + + }); + } + + function showButton(button) { + button.classList.remove('hide'); + } + + function hideButton(button) { + button.classList.add('hide'); + } + + function hasStreams(item, type) { + return item && item.MediaStreams && item.MediaStreams.filter(function (i) { + return i.Type == type; + }).length > 0; + } + + var currentImgUrl; + function updateNowPlayingInfo(context, state) { + + var item = state.NowPlayingItem; + var displayName = item ? MediaController.getNowPlayingNameHtml(item).replace('
', ' - ') : ''; + + context.querySelector('.nowPlayingPageTitle').innerHTML = displayName; + + if (displayName.length > 0) { + context.querySelector('.nowPlayingPageTitle').classList.remove('hide'); + } else { + context.querySelector('.nowPlayingPageTitle').classList.add('hide'); + } + + var url; + var backdropUrl = null; + + if (!item) { + } + else if (item.PrimaryImageTag) { + + url = ApiClient.getScaledImageUrl(item.PrimaryImageItemId, { + type: "Primary", + maxHeight: 300, + tag: item.PrimaryImageTag + }); + } + else if (item.BackdropImageTag) { + + url = ApiClient.getScaledImageUrl(item.BackdropItemId, { + type: "Backdrop", + maxHeight: 300, + tag: item.BackdropImageTag, + index: 0 + }); + + } else if (item.ThumbImageTag) { + + url = ApiClient.getScaledImageUrl(item.ThumbImageItemId, { + type: "Thumb", + maxHeight: 300, + tag: item.ThumbImageTag + }); + } + + if (url == currentImgUrl) { + return; + } + + if (item && item.BackdropImageTag) { + + backdropUrl = ApiClient.getScaledImageUrl(item.BackdropItemId, { + type: "Backdrop", + maxHeight: 300, + tag: item.BackdropImageTag, + index: 0 + }); + + } + + setImageUrl(context, url); + + if (item) { + + // This should be outside of the IF + // But for now, if you change songs but keep the same artist, the backdrop will flicker because in-between songs it clears out the image + if (!browser.mobile) { + // Exclude from mobile because it just doesn't perform well + Backdrops.setBackdropUrl(context, backdropUrl); + } + + ApiClient.getItem(Dashboard.getCurrentUserId(), item.Id).then(function (fullItem) { + context.querySelector('.nowPlayingPageUserDataButtons').innerHTML = LibraryBrowser.getUserDataIconsHtml(fullItem, false); + }); + } else { + context.querySelector('.nowPlayingPageUserDataButtons').innerHTML = ''; + } + } + + function setImageUrl(context, url) { + currentImgUrl = url; + + if (url) { + ImageLoader.lazyImage(context.querySelector('.nowPlayingPageImage'), url); + } else { + context.querySelector('.nowPlayingPageImage').style.backgroundImage = ''; + } + } + + function buttonEnabled(btn, enabled) { + btn.disabled = !enabled; + } + + function updateSupportedCommands(context, commands) { + + var all = context.querySelectorAll('.btnCommand'); + + for (var i = 0, length = all.length; i < length; i++) { + buttonEnabled(all[i], commands.indexOf(all[i].getAttribute('data-command')) != -1); + } + } + + function hideChapterMenu(page) { + + //$('.chapterMenuOverlay', page).hide(); + //$('.chapterMenu', page).hide(); + } + + return function () { + + var dlg; + var currentPlayer; + var lastPlayerState; + var lastUpdateTime = 0; + + var self = this; + var playlistNeedsRefresh = true; + + function toggleRepeat(player) { + + if (player && lastPlayerState) { + var state = lastPlayerState; + switch ((state.PlayState || {}).RepeatMode) { + case 'RepeatNone': + player.setRepeatMode('RepeatAll'); + break; + case 'RepeatAll': + player.setRepeatMode('RepeatOne'); + break; + case 'RepeatOne': + player.setRepeatMode('RepeatNone'); + break; + } + } + } + + function updatePlayerState(context, state) { + + lastPlayerState = state; + + var item = state.NowPlayingItem; + + var playerInfo = MediaController.getPlayerInfo(); + + var supportedCommands = playerInfo.supportedCommands; + var playState = state.PlayState || {}; + + buttonEnabled(context.querySelector('.btnToggleFullscreen'), item && item.MediaType == 'Video' && supportedCommands.indexOf('ToggleFullscreen') != -1); + buttonEnabled(context.querySelector('.btnAudioTracks'), hasStreams(item, 'Audio') && supportedCommands.indexOf('SetAudioStreamIndex') != -1); + buttonEnabled(context.querySelector('.btnSubtitles'), hasStreams(item, 'Subtitle') && supportedCommands.indexOf('SetSubtitleStreamIndex') != -1); + + if (item && item.Chapters && item.Chapters.length && playState.CanSeek) { + buttonEnabled(context.querySelector('.btnChapters'), true); + + } else { + buttonEnabled(context.querySelector('.btnChapters'), false); + hideChapterMenu(context); + } + + if (supportedCommands.indexOf('DisplayMessage') != -1) { + context.querySelector('.sendMessageSection').classList.remove('hide'); + } else { + context.querySelector('.sendMessageSection').classList.add('hide'); + } + if (supportedCommands.indexOf('SendString') != -1) { + context.querySelector('.sendTextSection').classList.remove('hide'); + } else { + context.querySelector('.sendTextSection').classList.add('hide'); + } + + buttonEnabled(context.querySelector('.btnStop'), item != null); + buttonEnabled(context.querySelector('.btnNextTrack'), item != null); + buttonEnabled(context.querySelector('.btnPreviousTrack'), item != null); + + var btnPause = context.querySelector('.btnPause'); + var btnPlay = context.querySelector('.btnPlay'); + + buttonEnabled(btnPause, item != null); + buttonEnabled(btnPlay, item != null); + + if (playState.IsPaused) { + + hideButton(btnPause); + showButton(btnPlay); + + } else { + + showButton(btnPause); + hideButton(btnPlay); + } + + var positionSlider = context.querySelector('.nowPlayingPositionSlider'); + + if (!positionSlider.dragging) { + + if (item && item.RunTimeTicks) { + + var pct = playState.PositionTicks / item.RunTimeTicks; + pct *= 100; + + positionSlider.value = pct; + + } else { + + positionSlider.value = 0; + } + + positionSlider.disabled = !playState.CanSeek; + } + + if (playState.PositionTicks == null) { + context.querySelector('.positionTime').innerHTML = '--:--'; + } else { + context.querySelector('.positionTime').innerHTML = Dashboard.getDisplayTime(playState.PositionTicks); + } + + if (item && item.RunTimeTicks != null) { + context.querySelector('.runtime').innerHTML = Dashboard.getDisplayTime(item.RunTimeTicks); + } else { + context.querySelector('.runtime').innerHTML = '--:--'; + } + + if (item && item.MediaType == 'Video') { + context.classList.remove('hideVideoButtons'); + } else { + context.classList.add('hideVideoButtons'); + } + + if (playerInfo.isLocalPlayer && AppInfo.hasPhysicalVolumeButtons) { + context.classList.add('hideVolumeButtons'); + } else { + context.classList.remove('hideVolumeButtons'); + } + + if (item && item.MediaType == 'Audio') { + context.querySelector('.buttonsRow2').classList.add('hide'); + } else { + context.querySelector('.buttonsRow2').classList.remove('hide'); + } + + var toggleRepeatButton = context.querySelector('.repeatToggleButton'); + + if (playState.RepeatMode == 'RepeatAll') { + toggleRepeatButton.icon = "repeat"; + toggleRepeatButton.classList.add('nowPlayingPageRepeatActive'); + } + else if (playState.RepeatMode == 'RepeatOne') { + toggleRepeatButton.icon = "repeat-one"; + toggleRepeatButton.classList.add('nowPlayingPageRepeatActive'); + } else { + toggleRepeatButton.icon = "repeat"; + toggleRepeatButton.classList.remove('nowPlayingPageRepeatActive'); + } + + updateNowPlayingInfo(context, state); + } + + function loadPlaylist(context) { + + var html = ''; + + //ApiClient.getItems(Dashboard.getCurrentUserId(), { + + // SortBy: "SortName", + // SortOrder: "Ascending", + // IncludeItemTypes: "Audio", + // Recursive: true, + // Fields: "PrimaryImageAspectRatio,SortName,MediaSourceCount,SyncInfo", + // StartIndex: 0, + // ImageTypeLimit: 1, + // EnableImageTypes: "Primary,Backdrop,Banner,Thumb", + // Limit: 100 + + //}).then(function (result) { + + // html += LibraryBrowser.getListViewHtml({ + // items: result.Items, + // smallIcon: true + // }); + + // $(".playlist", page).html(html).lazyChildren(); + //}); + + var playlistOpen = isPlaylistOpen(context); + + if (playlistOpen) { + + html += LibraryBrowser.getListViewHtml({ + items: MediaController.playlist(), + smallIcon: true + }); + + playlistNeedsRefresh = false; + } + + var deps = []; + + if (playlistOpen) { + deps.push('paper-icon-item'); + deps.push('paper-item-body'); + } + + require(deps, function () { + + var itemsContainer = context.querySelector('.playlist'); + + itemsContainer.innerHTML = html; + + if (playlistOpen) { + + var index = MediaController.currentPlaylistIndex(); + + if (index != -1) { + + var item = itemsContainer.querySelectorAll('.listItem')[index]; + if (item) { + var img = item.querySelector('.listviewImage'); + + img.classList.remove('lazy'); + img.classList.add('playlistIndexIndicatorImage'); + } + } + } + + ImageLoader.lazyChildren(itemsContainer); + }); + } + + function isPlaylistOpen(context) { + return context.querySelector('paper-tabs').selected == 2; + } + + function onStateChanged(e, state) { + + if (e.type == 'positionchange') { + // Try to avoid hammering the document with changes + var now = new Date().getTime(); + if ((now - lastUpdateTime) < 700) { + + return; + } + lastUpdateTime = now; + } + + updatePlayerState(dlg, state); + } + + function onPlaybackStart(e, state) { + + var player = this; + + player.beginPlayerUpdates(); + + onStateChanged.call(player, e, state); + + if (isPlaylistOpen(dlg)) { + loadPlaylist(dlg); + } else { + playlistNeedsRefresh = true; + } + } + + function onPlaybackStopped(e, state) { + + var player = this; + + player.endPlayerUpdates(); + + onStateChanged.call(player, e, {}); + + if (isPlaylistOpen(dlg)) { + loadPlaylist(dlg); + } else { + playlistNeedsRefresh = true; + } + } + + function releaseCurrentPlayer() { + + if (currentPlayer) { + + Events.off(currentPlayer, 'playbackstart', onPlaybackStart); + Events.off(currentPlayer, 'playbackstop', onPlaybackStopped); + Events.off(currentPlayer, 'volumechange', onStateChanged); + Events.off(currentPlayer, 'playstatechange', onStateChanged); + Events.off(currentPlayer, 'positionchange', onStateChanged); + + currentPlayer.endPlayerUpdates(); + currentPlayer = null; + } + } + + function bindToPlayer(context, player) { + + releaseCurrentPlayer(); + + currentPlayer = player; + + player.getPlayerState().then(function (state) { + + if (state.NowPlayingItem) { + player.beginPlayerUpdates(); + } + + onStateChanged.call(player, { type: 'init' }, state); + }); + + Events.on(player, 'playbackstart', onPlaybackStart); + Events.on(player, 'playbackstop', onPlaybackStopped); + Events.on(player, 'volumechange', onStateChanged); + Events.on(player, 'playstatechange', onStateChanged); + Events.on(player, 'positionchange', onStateChanged); + + var playerInfo = MediaController.getPlayerInfo(); + + var supportedCommands = playerInfo.supportedCommands; + + updateSupportedCommands(context, supportedCommands); + } + + function updateCastIcon(context) { + + var info = MediaController.getPlayerInfo(); + + if (info.isLocalPlayer) { + + context.querySelector('.nowPlayingCastIcon').icon = 'cast'; + context.querySelector('.nowPlayingSelectedPlayer').innerHTML = ''; + + } else { + + context.querySelector('.nowPlayingCastIcon').icon = 'cast-connected'; + context.querySelector('.nowPlayingSelectedPlayer').innerHTML = info.deviceName || info.name; + } + } + + function parentWithClass(elem, className) { + + while (!elem.classList || !elem.classList.contains(className)) { + elem = elem.parentNode; + + if (!elem) { + return null; + } + } + + return elem; + } + + function onContextClick(e) { + + var lnkPlayFromIndex = parentWithClass(e.target, 'lnkPlayFromIndex'); + if (lnkPlayFromIndex != null) { + var index = parseInt(lnkPlayFromIndex.getAttribute('data-index')); + + MediaController.currentPlaylistIndex(index); + loadPlaylist(context); + + return false; + } + var lnkRemoveFromPlaylist = parentWithClass(e.target, 'lnkRemoveFromPlaylist'); + if (lnkRemoveFromPlaylist != null) { + var index = parseInt(lnkRemoveFromPlaylist.getAttribute('data-index')); + + MediaController.removeFromPlaylist(index); + loadPlaylist(context); + + return false; + } + + var mediaItem = parentWithClass(e.target, 'mediaItem'); + if (mediaItem != null) { + var info = LibraryBrowser.getListItemInfo(mediaItem); + + MediaController.currentPlaylistIndex(info.index); + + return false; + } + } + + function bindEvents(context) { + + $('.btnCommand', context).on('click', function () { + + if (currentPlayer) { + + if (this.classList.contains('repeatToggleButton')) { + toggleRepeat(currentPlayer); + } else { + MediaController.sendCommand({ + Name: this.getAttribute('data-command') + + }, currentPlayer); + } + } + }); + + context.querySelector('.btnToggleFullscreen').addEventListener('click', function (e) { + + if (currentPlayer) { + MediaController.sendCommand({ + Name: e.target.getAttribute('data-command') + + }, currentPlayer); + } + }); + + context.querySelector('.btnAudioTracks').addEventListener('click', function (e) { + + if (currentPlayer && lastPlayerState && lastPlayerState.PlayState) { + + var currentIndex = lastPlayerState.PlayState.AudioStreamIndex; + showAudioMenu(context, currentPlayer, e.target, lastPlayerState.NowPlayingItem, currentIndex); + } + }); + + context.querySelector('.btnSubtitles').addEventListener('click', function (e) { + + if (currentPlayer && lastPlayerState && lastPlayerState.PlayState) { + + var currentIndex = lastPlayerState.PlayState.SubtitleStreamIndex; + showSubtitleMenu(context, currentPlayer, e.target, lastPlayerState.NowPlayingItem, currentIndex); + } + }); + + context.querySelector('.btnChapters').addEventListener('click', function () { + + //if (currentPlayer && lastPlayerState) { + + // var currentPositionTicks = lastPlayerState.PlayState.PositionTicks; + // showChapterMenu(context, lastPlayerState.NowPlayingItem, currentPositionTicks); + //} + }); + + context.querySelector('.btnStop').addEventListener('click', function () { + + if (currentPlayer) { + currentPlayer.stop(); + } + }); + + context.querySelector('.btnPlay').addEventListener('click', function () { + + if (currentPlayer) { + currentPlayer.unpause(); + } + }); + + context.querySelector('.btnPause').addEventListener('click', function () { + + if (currentPlayer) { + currentPlayer.pause(); + } + }); + + context.querySelector('.btnNextTrack').addEventListener('click', function () { + + if (currentPlayer) { + currentPlayer.nextTrack(); + } + }); + + context.querySelector('.btnPreviousTrack').addEventListener('click', function () { + + if (currentPlayer) { + currentPlayer.previousTrack(); + } + }); + + context.querySelector('.nowPlayingPositionSlider').addEventListener('change', function () { + + var value = this.value; + + if (currentPlayer && lastPlayerState) { + + var newPercent = parseFloat(value); + var newPositionTicks = (newPercent / 100) * lastPlayerState.NowPlayingItem.RunTimeTicks; + currentPlayer.seek(Math.floor(newPositionTicks)); + } + }); + + context.querySelector('.nowPlayingPositionSlider', context)._setPinValue = function (value) { + + var state = lastPlayerState; + + if (!state || !state.NowPlayingItem || !state.NowPlayingItem.RunTimeTicks) { + this.pinValue = '--:--'; + return; + } + + var ticks = state.NowPlayingItem.RunTimeTicks; + ticks /= 100; + ticks *= value; + + this.pinValue = Dashboard.getDisplayTime(ticks); + }; + + context.addEventListener('click', onContextClick); + } + + function onPlayerChange() { + + var context = dlg; + updateCastIcon(context); + bindToPlayer(context, MediaController.getCurrentPlayer()); + } + + function onMessageSubmit(e) { + + var form = e.target; + + MediaController.sendCommand({ + Name: 'DisplayMessage', + Arguments: { + + Header: $('#txtMessageTitle', form).val(), + Text: $('#txtMessageText', form).val() + } + + }, currentPlayer); + + $('input', form).val(''); + Dashboard.alert('Message sent.'); + + e.preventDefault(); + e.stopPropagation(); + return false; + } + + function onSendStringSubmit(e) { + + var form = e.target; + + MediaController.sendCommand({ + Name: 'SendString', + Arguments: { + + String: $('#txtTypeText', form).val() + } + + }, currentPlayer); + + $('input', form).val(''); + Dashboard.alert('Text sent.'); + + e.preventDefault(); + e.stopPropagation(); + return false; + } + + function showTab(index) { + + var all = dlg.querySelectorAll('.nowPlayingPageTab'); + + index = (index || 0).toString(); + + for (var i = 0, length = all.length; i < length; i++) { + + var tab = all[i]; + + if (tab.getAttribute('data-tab') == index) { + tab.classList.remove('hide'); + } else { + tab.classList.add('hide'); + } + } + } + + function init(context) { + + Dashboard.importCss('css/nowplaying.css'); + bindEvents(context); + + context.querySelector('.sendMessageForm').addEventListener('submit', onMessageSubmit); + context.querySelector('.typeTextForm').addEventListener('submit', onSendStringSubmit); + + context.querySelector('.nowPlayingCastIcon').addEventListener('click', function () { + MediaController.showPlayerSelection(); + }); + + context.querySelector('.btnExitRemoteControl').addEventListener('click', function () { + history.back(); + }); + + //context.querySelector('.btnSlideshow').addEventListener('click', function () { + // showSlideshowMenu(context); + //}); + + var tabs = context.querySelector('paper-tabs'); + + if (AppInfo.enableNowPlayingPageBottomTabs) { + tabs.classList.remove('hide'); + context.querySelector('.libraryViewNav').classList.add('hide'); + } else { + tabs.classList.add('hide'); + context.querySelector('.libraryViewNav').classList.remove('hide'); + } + + tabs.classList.add('bottom'); + tabs.alignBottom = true; + + tabs.addEventListener('iron-select', function (e) { + + var btn = context.querySelector('.libraryViewNav a.ui-btn-active'); + + if (btn) { + btn.classList.remove('ui-btn-active'); + } + + context.querySelector('.libraryViewNav a[data-index=\'' + e.target.selected + '\']').classList.add('ui-btn-active'); + + if (e.target.selected == 2 && playlistNeedsRefresh) { + loadPlaylist(context); + } + + showTab(e.target.selected); + }); + + $(context.querySelectorAll('.libraryViewNav a')).on('click', function () { + var newSelected = this.getAttribute('data-index'); + + tabs.selected = newSelected; + }); + + Events.on(MediaController, 'playerchange', onPlayerChange); + + $(context.querySelector('.itemsContainer')).createCardMenus(); + + } + + function onDialogClosed(e) { + + releaseCurrentPlayer(); + + Events.off(MediaController, 'playerchange', onPlayerChange); + + lastPlayerState = null; + } + + function onShow(context, tab) { + + currentImgUrl = null; + + bindToPlayer(context, MediaController.getCurrentPlayer()); + + var selected = tab == '#playlist' ? 2 : 0; + + if (AppInfo.enableNowPlayingPageBottomTabs) { + context.querySelector('paper-tabs').selected = selected; + } else { + + showTab(selected); + } + + updateCastIcon(context); + } + + self.init = function (context) { + + var html = ''; + + dlg = context; + html += '
'; + html += Globalize.translateDocument(getHeaderHtml()); + html += Globalize.translateDocument(getAnimatedPagesHtml()); + html += Globalize.translateDocument(getTabsHtml()); + html += '
'; + + dlg.innerHTML = html; + + init(dlg); + }; + + self.onShow = function () { + onShow(dlg, window.location.hash); + }; + + self.destroy = function () { + onDialogClosed(); + }; + + }; +}); \ No newline at end of file diff --git a/dashboard-ui/css/librarybrowser.css b/dashboard-ui/css/librarybrowser.css index 5b44106208..94f7dd6440 100644 --- a/dashboard-ui/css/librarybrowser.css +++ b/dashboard-ui/css/librarybrowser.css @@ -17,7 +17,7 @@ } .background-theme-b, paper-dialog.background-theme-b { - background-color: #202020; + background-color: #1A1A1A; /*background: radial-gradient(circle, #282828, #141414);*/ } diff --git a/dashboard-ui/css/nowplaying.css b/dashboard-ui/css/nowplaying.css index 71618ac253..efb7070fb7 100644 --- a/dashboard-ui/css/nowplaying.css +++ b/dashboard-ui/css/nowplaying.css @@ -17,9 +17,12 @@ display: inline-block !important; } -.nowPlayingPageImage img { - max-height: 360px; - max-width: 360px; +.nowPlayingPageImage { + height: 360px; + width: 360px; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; } .nowPlayingPageTimeContainer { @@ -89,9 +92,9 @@ @media all and (max-width: 700px) { - .nowPlayingPageImage img { - max-height: 160px; - max-width: 200px; + .nowPlayingPageImage { + height: 160px; + width: 160px; } } @@ -109,16 +112,17 @@ margin: 2px 0; } - .nowPlayingPageImage img { - max-height: 160px; - max-width: 220px; + .nowPlayingPageImage { + height: 160px; + width: 160px; } } @media all and (max-height: 500px) { - .nowPlayingPageImage img { - max-height: 120px; + .nowPlayingPageImage { + height: 120px; + width: 120px; } } @@ -130,7 +134,8 @@ } .nowPlayingPageTitle { - margin: .5em 0; + margin: 1.5em auto .5em; + max-width: 50%; } .nowPlayingInfoButtons { @@ -140,7 +145,7 @@ @media all and (min-height: 600px) { .nowPlayingPageTitle { - margin: 1em 0; + margin-top: 2em; } .nowPlayingInfoButtons { @@ -173,16 +178,6 @@ } @media (orientation: landscape) and (max-height: 400px) { - .nowPlayingPageTitle { - margin: 0 auto; - width: 50%; - position: absolute; - text-align: center; - left: 0; - right: 0; - top: -20px; - } - .nowPlayingPage .btnCommand, .nowPlayingPage .btnPlayStateCommand { width: 60px; height: 60px; @@ -190,15 +185,6 @@ } @media (orientation: portrait) and (max-height: 600px) { - .nowPlayingPageTitle { - margin: 0 auto; - width: 50%; - position: absolute; - text-align: center; - left: 0; - right: 0; - top: -20px; - } .nowPlayingPage .btnCommand, .nowPlayingPage .btnPlayStateCommand { width: 60px; @@ -224,3 +210,11 @@ width: 40px; height: 40px; } + +.hideVideoButtons .videoButton { + visibility: hidden; +} + +.hideVolumeButtons .volumeButton { + visibility: hidden; +} diff --git a/dashboard-ui/css/nowplayingbar.css b/dashboard-ui/css/nowplayingbar.css index 52ae8c76c0..3c9cae8b57 100644 --- a/dashboard-ui/css/nowplayingbar.css +++ b/dashboard-ui/css/nowplayingbar.css @@ -109,13 +109,13 @@ height: 80px; } - .nowPlayingBar .nowPlayingImage { - height: 80px; - width: 80px; - background-position: center center; - background-repeat: no-repeat; - background-size: cover; - } + .nowPlayingBar .nowPlayingImage { + width: 80px; + height: 80px; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + } .nowPlayingBarText { display: inline-block; @@ -280,10 +280,15 @@ display: none !important; } - .nowPlayingBar, .nowPlayingImage img { + .nowPlayingBar { height: 70px; } + .nowPlayingBar .nowPlayingImage { + height: 70px; + width: 70px; + } + .nowPlayingBarPositionContainer { left: 70px; } diff --git a/dashboard-ui/devices/android/android.css b/dashboard-ui/devices/android/android.css index 2cc8e08460..0c79a2940d 100644 --- a/dashboard-ui/devices/android/android.css +++ b/dashboard-ui/devices/android/android.css @@ -7,7 +7,7 @@ } .background-theme-b, paper-dialog.background-theme-b { - background-color: #1b1b1b; + background-color: #1A1A1A; } .defaultBackground .cardImage { diff --git a/dashboard-ui/music.html b/dashboard-ui/music.html index 84a73af00a..ac162b37ea 100644 --- a/dashboard-ui/music.html +++ b/dashboard-ui/music.html @@ -22,7 +22,7 @@ ${TabArtists} ${TabSongs} ${TabGenres} - ${TabFolders} + ${TabFolders} diff --git a/dashboard-ui/nowplaying.html b/dashboard-ui/nowplaying.html index 6d21988eae..7f04edfc00 100644 --- a/dashboard-ui/nowplaying.html +++ b/dashboard-ui/nowplaying.html @@ -4,174 +4,14 @@ Emby -
+
-
-
- ${TabNowPlaying} - ${TabControls} - ${TabPlaylist} -
+
+
-
- -
-
- - - -
-
- - - -
- -
-
- - - -
-
- - - - - -
-
- - - - -
- -
- - - - -
-
- -
-
-
-
- -
-
- -
-
- - - - -
-
- -
-
- - -
-
-
- - - - -
-
- - - -
-
-
- -
-

${HeaderSendMessage}

-
- -
-
-
- - -
-
-
- - -
-

- -

-
- -
-
-
-

${HeaderTypeText}

-
- -
-
-
- - -
-

- -

-
- -
-
-
-
- -
-
-
-
-
- - - - - - - ${TabNowPlaying} - ${TabControls} - ${TabPlaylist} - -
diff --git a/dashboard-ui/scripts/nowplayingbar.js b/dashboard-ui/scripts/nowplayingbar.js index 148490e42e..42f770782a 100644 --- a/dashboard-ui/scripts/nowplayingbar.js +++ b/dashboard-ui/scripts/nowplayingbar.js @@ -1,4 +1,4 @@ -(function (window, document, $, setTimeout, clearTimeout) { +define([], function () { var currentPlayer; @@ -60,7 +60,7 @@ html += ''; html += ''; - html += ''; + html += ''; html += ''; html += '
'; @@ -183,11 +183,14 @@ } }); - $('.playlistButton', elem).on('click', function () { + elem.querySelector('.remoteControlButton').addEventListener('click', function () { - $.mobile.changePage('nowplaying.html', { - dataUrl: 'nowplaying.html#playlist' - }); + showRemoteControl(); + }); + + elem.querySelector('.playlistButton').addEventListener('click', function () { + + showRemoteControl('playlist'); }); toggleRepeatButton = $('.toggleRepeatButton', elem).on('click', function () { @@ -249,6 +252,17 @@ }, 300); } + function showRemoteControl(tab) { + + if (tab) { + $.mobile.changePage('nowplaying.html', { + dataUrl: 'nowplaying.html#' + tab + }); + } else { + Dashboard.navigate('nowplaying.html'); + } + } + var nowPlayingBarElement; function getNowPlayingBar() { @@ -645,4 +659,4 @@ bindToPlayer(MediaController.getCurrentPlayer()); -})(window, document, jQuery, setTimeout, clearTimeout); \ No newline at end of file +}); \ No newline at end of file diff --git a/dashboard-ui/scripts/nowplayingpage.js b/dashboard-ui/scripts/nowplayingpage.js index 9f8592536e..297fbc8441 100644 --- a/dashboard-ui/scripts/nowplayingpage.js +++ b/dashboard-ui/scripts/nowplayingpage.js @@ -1,919 +1,43 @@ (function (window, document, $, setTimeout, clearTimeout) { - var currentPlayer; - var lastPlayerState; - - function populateChapters(elem, chapters, itemId, runtimeTicks) { - - var html = ''; - - for (var i = 0, length = chapters.length; i < length; i++) { - - var chapter = chapters[i]; - - html += '
'; - - var imgUrl; - - if (chapter.ImageTag) { - - imgUrl = ApiClient.getScaledImageUrl(itemId, { - width: 240, - tag: chapter.ImageTag, - type: "Chapter", - index: i - }); - - } else { - imgUrl = "css/images/items/list/chapter.png"; - } - - var dataSrc = ' data-src="' + imgUrl + '"'; - // TODO: This markup needs to be converted to the newer card layout pattern - html += '
'; - - html += '
'; - - if (chapter.Name) { - html += "
"; - html += chapter.Name; - html += "
"; - } - - html += "
"; - var pct = 100 * (chapter.StartPositionTicks / runtimeTicks); - html += ''; - html += "
"; - - html += "
"; - - html += "
"; - - html += "
"; - } - - elem.innerHTML = html; - ImageLoader.lazyChildren(elem); - } - - function selectCurrentChapter(elem, positionTicks) { - - var elems = $('.chapterPosterItem', elem).removeClass('currentChapter'); - - var matches = elems.get().filter(function (i) { - - var ticks = i.getAttribute('data-positionticks'); - - return positionTicks >= ticks; - - }); - - var chapterElem = matches[matches.length - 1]; - - chapterElem.classList.add('currentChapter'); - - chapterElem.scrollIntoView(); - - elem.scrollLeft += 50; - } - - function showChapterMenu(page, item, currentPositionTicks) { - - $('.chapterMenuOverlay', page).show(); - - var elem = page.querySelector('.chapterMenu'); - $(elem).show(); - - if (item.Id == elem.getAttribute('data-itemid')) { - - selectCurrentChapter(elem, currentPositionTicks); - return; - } - - var innerElem = elem.querySelector('.chapterMenuInner'); - - populateChapters(innerElem, item.Chapters, item.Id, item.RunTimeTicks); - - elem.setAttribute('data-itemid', item.Id); - - selectCurrentChapter(elem, currentPositionTicks); - } - - function hideChapterMenu(page) { - - $('.chapterMenuOverlay', page).hide(); - $('.chapterMenu', page).hide(); - } - - function showAudioMenu(page, button, item, currentIndex) { - - var streams = (item.MediaStreams || []).filter(function (i) { - - return i.Type == 'Audio'; - }); - - var menuItems = streams.map(function (s) { - - var name = (s.Codec || '').toUpperCase(); - - if (s.Profile) { - name += ' ' + s.Profile; - } - - if (s.Language) { - name += ' · ' + s.Language; - } - if (s.Layout) { - name += ' · ' + s.Layout; - } - else if (s.Channels) { - name += ' · ' + s.Channels + ' ch'; - } - - var menuItem = { - name: name, - id: s.Index - }; - - if (s.Index == currentIndex) { - menuItem.ironIcon = 'check'; - } - - return menuItem; - }); - - require(['actionsheet'], function (actionsheet) { - - actionsheet.show({ - items: menuItems, - positionTo: button, - callback: function (id) { - - currentPlayer.setAudioStreamIndex(parseInt(id)); - } - }); - - }); - } - - function showSubtitleMenu(page, button, item, currentIndex) { - - var streams = (item.MediaStreams || []).filter(function (i) { - - return i.Type == 'Subtitle'; - }); - - var menuItems = streams.map(function (s) { - - var name = (s.Language || Globalize.translate('LabelUnknownLanguage')); - - if (s.IsDefault && s.IsForced) { - name += ' · ' + Globalize.translate('LabelDefaultForcedStream'); - } - else if (s.IsDefault) { - name += ' · ' + Globalize.translate('LabelDefaultStream'); - } - else if (s.IsForced) { - name += ' · ' + Globalize.translate('LabelForcedStream'); - } - - if (s.Codec) { - name += ' · ' + s.Codec.toUpperCase(); - } - - var menuItem = { - name: name, - id: s.Index - }; - - if (s.Index == currentIndex) { - menuItem.ironIcon = 'check'; - } - - return menuItem; - }); - alert(currentIndex); - menuItems.unshift({ - id: -1, - name: Globalize.translate('ButtonOff'), - ironIcon: currentIndex == null ? 'check' : null - }); - - require(['actionsheet'], function (actionsheet) { - - actionsheet.show({ - items: menuItems, - positionTo: button, - callback: function (id) { - - currentPlayer.setSubtitleStreamIndex(parseInt(id)); - } - }); - - }); - } - - function toggleRepeat(player) { - - if (player && lastPlayerState) { - var state = lastPlayerState; - switch ((state.PlayState || {}).RepeatMode) { - case 'RepeatNone': - player.setRepeatMode('RepeatAll'); - break; - case 'RepeatAll': - player.setRepeatMode('RepeatOne'); - break; - case 'RepeatOne': - player.setRepeatMode('RepeatNone'); - break; - } - } - } - - function bindEvents(page) { - - $('.tabButton', page).on('click', function () { - - var elem = $('.' + this.getAttribute('data-tab'), page); - elem.siblings('.tabContent').hide(); - - elem.show(); - - $('.tabButton', page).removeClass('ui-btn-active'); - $(this).addClass('ui-btn-active'); - }); - - $('.chapterMenuOverlay', page).on('click', function () { - - hideChapterMenu(page); - }); - - $('.chapterMenu', page).on('click', '.chapterPosterItem', function () { - - if (currentPlayer) { - var ticks = this.getAttribute('data-positionticks') || '0'; - - currentPlayer.seek(parseInt(ticks)); - } - - hideChapterMenu(page); - }); - - $('.btnCommand,.btnToggleFullscreen', page).on('click', function () { - - if (currentPlayer) { - - if (this.classList.contains('repeatToggleButton')) { - toggleRepeat(currentPlayer); - } else { - MediaController.sendCommand({ - Name: this.getAttribute('data-command') - - }, currentPlayer); - } - } - }); - - $('.btnAudioTracks', page).on('click', function () { - - if (currentPlayer && lastPlayerState && lastPlayerState.PlayState) { - - var currentIndex = lastPlayerState.PlayState.AudioStreamIndex; - showAudioMenu(page, this, lastPlayerState.NowPlayingItem, currentIndex); - } - }); - - $('.btnSubtitles', page).on('click', function () { - - if (currentPlayer && lastPlayerState && lastPlayerState.PlayState) { - - var currentIndex = lastPlayerState.PlayState.SubtitleStreamIndex; - showSubtitleMenu(page, this, lastPlayerState.NowPlayingItem, currentIndex); - } - }); - - $('.btnChapters', page).on('click', function () { - - if (currentPlayer && lastPlayerState) { - - var currentPositionTicks = lastPlayerState.PlayState.PositionTicks; - showChapterMenu(page, lastPlayerState.NowPlayingItem, currentPositionTicks); - } - }); - - $('.btnStop', page).on('click', function () { - - if (currentPlayer) { - currentPlayer.stop(); - } - }); - - $('.btnPlay', page).on('click', function () { - - if (currentPlayer) { - currentPlayer.unpause(); - } - }); - - $('.btnPause', page).on('click', function () { - - if (currentPlayer) { - currentPlayer.pause(); - } - }); - - $('.btnNextTrack', page).on('click', function () { - - if (currentPlayer) { - currentPlayer.nextTrack(); - } - }); - - $('.btnPreviousTrack', page).on('click', function () { - - if (currentPlayer) { - currentPlayer.previousTrack(); - } - }); - - $('.nowPlayingPositionSlider', page).on('change', function () { - - var value = this.value; - - if (currentPlayer && lastPlayerState) { - - var newPercent = parseFloat(value); - var newPositionTicks = (newPercent / 100) * lastPlayerState.NowPlayingItem.RunTimeTicks; - currentPlayer.seek(Math.floor(newPositionTicks)); - } - }); - - $('.nowPlayingPositionSlider', page)[0]._setPinValue = function (value) { - - var state = lastPlayerState; - - if (!state || !state.NowPlayingItem || !state.NowPlayingItem.RunTimeTicks) { - this.pinValue = '--:--'; - return; - } - - var ticks = state.NowPlayingItem.RunTimeTicks; - ticks /= 100; - ticks *= value; - - this.pinValue = Dashboard.getDisplayTime(ticks); - }; - - $(page).on('click', '.lnkPlayFromIndex', function () { - - var index = parseInt(this.getAttribute('data-index')); - - MediaController.currentPlaylistIndex(index); - loadPlaylist(page); - - }).on('click', '.lnkRemoveFromPlaylist', function () { - - var index = parseInt(this.getAttribute('data-index')); - - MediaController.removeFromPlaylist(index); - loadPlaylist(page); - }); - - Events.on(page, 'click', '.mediaItem', onListItemClick); - } - - function onPlaybackStart(e, state) { - - var player = this; - - player.beginPlayerUpdates(); - - onStateChanged.call(player, e, state); - loadPlaylist($($.mobile.activePage)[0]); - } - - function onPlaybackStopped(e, state) { - - var player = this; - - player.endPlayerUpdates(); - - onStateChanged.call(player, e, {}); - loadPlaylist($($.mobile.activePage)[0]); - } - - var lastUpdateTime = 0; - - function onStateChanged(e, state) { - - if (e.type == 'positionchange') { - // Try to avoid hammering the document with changes - var now = new Date().getTime(); - if ((now - lastUpdateTime) < 700) { - - return; - } - lastUpdateTime = now; - } - - updatePlayerState($($.mobile.activePage)[0], state); - } - - function showButton(button) { - button.removeClass('hide'); - } - - function hideButton(button) { - button.addClass('hide'); - } - - function hasStreams(item, type) { - return item && item.MediaStreams && item.MediaStreams.filter(function (i) { - return i.Type == type; - }).length > 0; - } - - function updatePlayerState(page, state) { - - lastPlayerState = state; - - var item = state.NowPlayingItem; - - var playerInfo = MediaController.getPlayerInfo(); - - var supportedCommands = playerInfo.supportedCommands; - var playState = state.PlayState || {}; - - $('.btnToggleFullscreen', page).buttonEnabled(item && item.MediaType == 'Video' && supportedCommands.indexOf('ToggleFullscreen') != -1); - - $('.btnAudioTracks', page).buttonEnabled(hasStreams(item, 'Audio') && supportedCommands.indexOf('SetAudioStreamIndex') != -1); - $('.btnSubtitles', page).buttonEnabled(hasStreams(item, 'Subtitle') && supportedCommands.indexOf('SetSubtitleStreamIndex') != -1); - - if (item && item.Chapters && item.Chapters.length && playState.CanSeek) { - $('.btnChapters', page).buttonEnabled(true); - - } else { - $('.btnChapters', page).buttonEnabled(false); - hideChapterMenu(page); - } - - $('.sendMessageElement', page).buttonEnabled(supportedCommands.indexOf('DisplayMessage') != -1); - $('.typeTextElement', page).buttonEnabled(supportedCommands.indexOf('SendString') != -1); - - $('.btnStop', page).buttonEnabled(item != null); - $('.btnNextTrack', page).buttonEnabled(item != null); - $('.btnPreviousTrack', page).buttonEnabled(item != null); - - var btnPause = $('.btnPause', page).buttonEnabled(item != null); - var btnPlay = $('.btnPlay', page).buttonEnabled(item != null); - - if (playState.IsPaused) { - - hideButton(btnPause); - showButton(btnPlay); - - } else { - - showButton(btnPause); - hideButton(btnPlay); - } - - var positionSlider = $('.nowPlayingPositionSlider', page)[0]; - - if (!positionSlider.dragging) { - - if (item && item.RunTimeTicks) { - - var pct = playState.PositionTicks / item.RunTimeTicks; - pct *= 100; - - positionSlider.value = pct; - - } else { - - positionSlider.value = 0; - } - - positionSlider.disabled = !playState.CanSeek; - } - - if (playState.PositionTicks == null) { - $('.positionTime', page).html('--:--'); - } else { - $('.positionTime', page).html(Dashboard.getDisplayTime(playState.PositionTicks)); - } - - if (item && item.RunTimeTicks != null) { - $('.runtime', page).html(Dashboard.getDisplayTime(item.RunTimeTicks)); - } else { - $('.runtime', page).html('--:--'); - } - - if (item && item.MediaType == 'Video') { - $('.videoButton', page).css('visibility', 'visible'); - } else { - $('.videoButton', page).css('visibility', 'hidden'); - } - - if (playerInfo.isLocalPlayer && AppInfo.hasPhysicalVolumeButtons) { - $('.volumeButton', page).css('visibility', 'hidden'); - } else { - $('.volumeButton', page).css('visibility', 'visible'); - } - - if (item && item.MediaType == 'Audio') { - $('.buttonsRow2', page).hide(); - } else { - $('.buttonsRow2', page).show(); - } - - var toggleRepeatButton = page.querySelector('.repeatToggleButton'); - - if (playState.RepeatMode == 'RepeatAll') { - toggleRepeatButton.icon = "repeat"; - toggleRepeatButton.classList.add('nowPlayingPageRepeatActive'); - } - else if (playState.RepeatMode == 'RepeatOne') { - toggleRepeatButton.icon = "repeat-one"; - toggleRepeatButton.classList.add('nowPlayingPageRepeatActive'); - } else { - toggleRepeatButton.icon = "repeat"; - toggleRepeatButton.classList.remove('nowPlayingPageRepeatActive'); - } - - updateNowPlayingInfo(page, state); - } - - var currentImgUrl; - function updateNowPlayingInfo(page, state) { - - var item = state.NowPlayingItem; - var displayName = item ? MediaController.getNowPlayingNameHtml(item).replace('
', ' - ') : ''; - - $('.nowPlayingPageTitle', page).html(displayName); - - if (displayName.length > 0) { - $('.nowPlayingPageTitle', page).removeClass('hide'); - } else { - $('.nowPlayingPageTitle', page).addClass('hide'); - } - - var url; - var backdropUrl = null; - - if (!item) { - } - else if (item.PrimaryImageTag) { - - url = ApiClient.getScaledImageUrl(item.PrimaryImageItemId, { - type: "Primary", - height: 300, - tag: item.PrimaryImageTag - }); - } - else if (item.BackdropImageTag) { - - url = ApiClient.getScaledImageUrl(item.BackdropItemId, { - type: "Backdrop", - height: 300, - tag: item.BackdropImageTag, - index: 0 - }); - - } else if (item.ThumbImageTag) { - - url = ApiClient.getScaledImageUrl(item.ThumbImageItemId, { - type: "Thumb", - height: 300, - tag: item.ThumbImageTag - }); - } - - if (url == currentImgUrl) { - return; - } - - if (item && item.BackdropImageTag) { - - backdropUrl = ApiClient.getScaledImageUrl(item.BackdropItemId, { - type: "Backdrop", - maxWidth: $(window).width(), - tag: item.BackdropImageTag, - index: 0 - }); - - } - - setImageUrl(page, url); - - if (item) { - - // This should be outside of the IF - // But for now, if you change songs but keep the same artist, the backdrop will flicker because in-between songs it clears out the image - if (!browserInfo.mobile) { - // Exclude from mobile because it just doesn't perform well - Backdrops.setBackdropUrl(page, backdropUrl); - } - - ApiClient.getItem(Dashboard.getCurrentUserId(), item.Id).then(function (fullItem) { - page.querySelector('.nowPlayingPageUserDataButtons').innerHTML = LibraryBrowser.getUserDataIconsHtml(fullItem, false); - }); - } else { - page.querySelector('.nowPlayingPageUserDataButtons').innerHTML = ''; - } - } - - function setImageUrl(page, url) { - currentImgUrl = url; - - $('.nowPlayingPageImage', page).html(url ? '' : ''); - } - - function updateSupportedCommands(page, commands) { - - $('.btnCommand', page).each(function () { - - $(this).buttonEnabled(commands.indexOf(this.getAttribute('data-command')) != -1); - - }); - } - - function releaseCurrentPlayer() { - - if (currentPlayer) { - - Events.off(currentPlayer, 'playbackstart', onPlaybackStart); - Events.off(currentPlayer, 'playbackstop', onPlaybackStopped); - Events.off(currentPlayer, 'volumechange', onStateChanged); - Events.off(currentPlayer, 'playstatechange', onStateChanged); - Events.off(currentPlayer, 'positionchange', onStateChanged); - - currentPlayer.endPlayerUpdates(); - currentPlayer = null; - } - } - - function bindToPlayer(page, player) { - - releaseCurrentPlayer(); - - currentPlayer = player; - - player.getPlayerState().then(function (state) { - - if (state.NowPlayingItem) { - player.beginPlayerUpdates(); - } - - onStateChanged.call(player, { type: 'init' }, state); - }); - - Events.on(player, 'playbackstart', onPlaybackStart); - Events.on(player, 'playbackstop', onPlaybackStopped); - Events.on(player, 'volumechange', onStateChanged); - Events.on(player, 'playstatechange', onStateChanged); - Events.on(player, 'positionchange', onStateChanged); - - var playerInfo = MediaController.getPlayerInfo(); - - var supportedCommands = playerInfo.supportedCommands; - - updateSupportedCommands(page, supportedCommands); - } - - function loadPlaylist(page) { - - var html = ''; - - //ApiClient.getItems(Dashboard.getCurrentUserId(), { - - // SortBy: "SortName", - // SortOrder: "Ascending", - // IncludeItemTypes: "Audio", - // Recursive: true, - // Fields: "PrimaryImageAspectRatio,SortName,MediaSourceCount,SyncInfo", - // StartIndex: 0, - // ImageTypeLimit: 1, - // EnableImageTypes: "Primary,Backdrop,Banner,Thumb", - // Limit: 100 - - //}).then(function (result) { - - // html += LibraryBrowser.getListViewHtml({ - // items: result.Items, - // smallIcon: true - // }); - - // $(".playlist", page).html(html).lazyChildren(); - //}); - - html += LibraryBrowser.getListViewHtml({ - items: MediaController.playlist(), - smallIcon: true - }); - - var itemsContainer = page.querySelector('.playlist'); - itemsContainer.innerHTML = html; - - var index = MediaController.currentPlaylistIndex(); - - if (index != -1) { - - var item = itemsContainer.querySelectorAll('.listItem')[index]; - if (item) { - var img = item.querySelector('.listviewImage'); - - img.classList.remove('lazy'); - img.classList.add('playlistIndexIndicatorImage'); - } - } - - ImageLoader.lazyChildren(itemsContainer); - } - - function onListItemClick(e) { - - var info = LibraryBrowser.getListItemInfo(this); - - MediaController.currentPlaylistIndex(info.index); - - return false; - } - - function updateCastIcon() { - - var info = MediaController.getPlayerInfo(); - - if (info.isLocalPlayer) { - - $('.nowPlayingCastIcon').each(function () { - this.icon = 'cast'; - }); - $('.nowPlayingSelectedPlayer').html(''); - - } else { - - $('.nowPlayingCastIcon').each(function () { - this.icon = 'cast-connected'; - }); - - $('.nowPlayingSelectedPlayer').html((info.deviceName || info.name)); - } - } - - function onPlayerChange() { - bindToPlayer($($.mobile.activePage)[0], MediaController.getCurrentPlayer()); - } - - function showSlideshowMenu(page) { - require(['scripts/slideshow'], function () { - SlideShow.showMenu(); - }); - } - pageIdOn('pageinit', "nowPlayingPage", function () { var page = this; - Dashboard.importCss('css/nowplaying.css'); - bindEvents(page); - - $('.sendMessageForm').off('submit', NowPlayingPage.onMessageSubmit).on('submit', NowPlayingPage.onMessageSubmit); - $('.typeTextForm').off('submit', NowPlayingPage.onSendStringSubmit).on('submit', NowPlayingPage.onSendStringSubmit); - - $('.requiresJqmCreate', this).trigger('create'); - - $('.btnSlideshow').on('click', function () { - showSlideshowMenu(page); + require(['components/remotecontrol'], function (remotecontrolFactory) { + page.remoteControl = new remotecontrolFactory(); + page.remoteControl.init(page.querySelector('.remoteControlContent')); + page.remoteControl.onShow(); + page.remoteControlInitComplete = true; }); - - var tabs = page.querySelector('paper-tabs'); - - if (AppInfo.enableNowPlayingPageBottomTabs) { - tabs.classList.remove('hide'); - page.querySelector('.libraryViewNav').classList.add('hide'); - } else { - tabs.classList.add('hide'); - page.querySelector('.libraryViewNav').classList.remove('hide'); - } - - tabs.classList.add('bottom'); - tabs.alignBottom = true; - LibraryBrowser.configureSwipeTabs(page, tabs, page.querySelector('neon-animated-pages')); - - $(tabs).on('iron-select', function () { - page.querySelector('neon-animated-pages').selected = this.selected; - }); - - $(page.querySelector('neon-animated-pages')).on('iron-select', function () { - var btn = page.querySelector('.libraryViewNav a.ui-btn-active'); - - if (btn) { - btn.classList.remove('ui-btn-active'); - } - - page.querySelector('.libraryViewNav a[data-index=\'' + this.selected + '\']').classList.add('ui-btn-active'); - }); - - $(page.querySelectorAll('.libraryViewNav a')).on('click', function () { - var newSelected = this.getAttribute('data-index'); - - if (AppInfo.enableNowPlayingPageBottomTabs) { - tabs.selected = newSelected; - } else { - page.querySelector('neon-animated-pages').selected = newSelected; - } - }); - - Events.on(MediaController, 'playerchange', function () { - updateCastIcon(page); - }); - }); + pageIdOn('pagebeforeshow', "nowPlayingPage", function () { - $(document.body).addClass('hiddenViewMenuBar').addClass('hiddenNowPlayingBar'); var page = this; - currentImgUrl = null; + document.body.classList.add('hiddenViewMenuBar'); + document.body.classList.add('hiddenNowPlayingBar'); - Events.on(MediaController, 'playerchange', onPlayerChange); + if (page.remoteControl) { - bindToPlayer(page, MediaController.getCurrentPlayer()); - - loadPlaylist(page); - - var tab = window.location.hash; - var selected = tab == '#playlist' ? 2 : 0;; - - this.querySelector('paper-tabs').selected = selected; - - if (AppInfo.enableNowPlayingPageBottomTabs) { - this.querySelector('paper-tabs').selected = selected; - } else { - - // hack alert. doing this because the neon elements don't seem to be initialized yet - setTimeout(function () { - - page.querySelector('neon-animated-pages').selected = selected; - }, 1000); + if (!page.remoteControlInitComplete) { + page.remoteControlInitComplete = true; + } else { + page.remoteControl.onShow(); + } } - - updateCastIcon(page); - }); + pageIdOn('pagebeforehide', "nowPlayingPage", function () { - releaseCurrentPlayer(); + var page = this; - Events.off(MediaController, 'playerchange', onPlayerChange); - - lastPlayerState = null; - $(document.body).removeClass('hiddenViewMenuBar').removeClass('hiddenNowPlayingBar'); + if (page.remoteControl) { + page.remoteControl.destroy(); + } + document.body.classList.remove('hiddenViewMenuBar'); + document.body.classList.remove('hiddenNowPlayingBar'); }); - window.NowPlayingPage = { - - onMessageSubmit: function () { - - var form = this; - - MediaController.sendCommand({ - Name: 'DisplayMessage', - Arguments: { - - Header: $('#txtMessageTitle', form).val(), - Text: $('#txtMessageText', form).val() - } - - }, currentPlayer); - - $('input', form).val(''); - Dashboard.alert('Message sent.'); - - return false; - }, - - onSendStringSubmit: function () { - - var form = this; - - MediaController.sendCommand({ - Name: 'SendString', - Arguments: { - - String: $('#txtTypeText', form).val() - } - - }, currentPlayer); - - $('input', form).val(''); - Dashboard.alert('Text sent.'); - - return false; - } - - }; - })(window, document, jQuery, setTimeout, clearTimeout); \ No newline at end of file