diff --git a/dashboard-ui/css/remotecontrol.css b/dashboard-ui/css/remotecontrol.css new file mode 100644 index 0000000000..524ff84329 --- /dev/null +++ b/dashboard-ui/css/remotecontrol.css @@ -0,0 +1,95 @@ +#remoteControlFlyout { + width: 300px; + min-height: 400px; +} + +.playMenuOptions { + max-height: 200px; + overflow-y: auto; + border: 1px solid #aaa; +} + +.tblRemoteControl { + width: 100%; + border-spacing: 0; + border-collapse: collapse; +} + + .tblRemoteControl tbody tr:hover { + background: #ddd; + } + + .tblRemoteControl td { + padding: 2px 5px; + border-top: 1px solid #ccc; + text-align: left; + } + + .tblRemoteControl th { + padding: 2px 5px; + text-align: left; + } + + .tblRemoteControl th:first-child, .tblRemoteControl td:first-child { + padding-left: 0; + padding-right: 0; + } + +.tblRemoteControlNoHeader tr:first-child td { + border-top: 0; +} + +.tdSelectPlayTime, .tdSelectItem { + vertical-align: middle!important; + width: 30px; +} + +.tdRemoteControlImage { + width: 100px; +} + +.tblRemoteControl img { + height: 50px; +} + +@media all and (max-width: 400px) { + .nowPlayingCell { + display: none; + } +} + +@media all and (min-height: 500px) { + #remoteControlFlyout { + min-height: 450px; + } +} + +@media all and (min-height: 600px) { + #remoteControlFlyout { + min-height: 500px; + } +} + +@media all and (min-height: 800px) { + .playMenuOptions { + max-height: 300px; + } +} + +@media all and (min-width: 500px) { + #remoteControlFlyout { + width: 450px; + } +} + +@media all and (min-width: 600px) { + #remoteControlFlyout { + width: 550px; + } +} + +@media all and (min-width: 700px) { + #remoteControlFlyout { + width: 650px; + } +} diff --git a/dashboard-ui/scripts/Itemdetailpage.js b/dashboard-ui/scripts/Itemdetailpage.js index 2c19c85239..6b7f4d4a59 100644 --- a/dashboard-ui/scripts/Itemdetailpage.js +++ b/dashboard-ui/scripts/Itemdetailpage.js @@ -866,7 +866,15 @@ $('#btnRemote', page).on('click', function () { - RemoteControl.showMenu(page, currentItem); + RemoteControl.showMenu({ + + item: currentItem, + context: getContext(currentItem), + + themeSongs: $('#themeSongsCollapsible:visible', page).length > 0, + + themeVideos: $('#themeVideosCollapsible:visible', page).length > 0 + }); }); }).on('pageshow', "#itemDetailPage", function () { diff --git a/dashboard-ui/scripts/itembynamedetailpage.js b/dashboard-ui/scripts/itembynamedetailpage.js index 4869388769..4efb475087 100644 --- a/dashboard-ui/scripts/itembynamedetailpage.js +++ b/dashboard-ui/scripts/itembynamedetailpage.js @@ -470,7 +470,7 @@ $('#btnRemote', page).on('click', function () { - RemoteControl.showMenu(page, currentItem, getParameterByName('context') || ''); + RemoteControl.showMenu({ item: currentItem, context: getParameterByName('context') || '' }); }); }).on('pageshow', "#itemByNameDetailPage", function () { diff --git a/dashboard-ui/scripts/remotecontrol.js b/dashboard-ui/scripts/remotecontrol.js index 7291818a02..c040f8d527 100644 --- a/dashboard-ui/scripts/remotecontrol.js +++ b/dashboard-ui/scripts/remotecontrol.js @@ -1,23 +1,42 @@ (function (window, document, $) { - function showMenu(page, item, context, sessionsPromise, usersPromise) { + function showMenu(options, sessionsPromise, usersPromise) { + + var playFromRendered; + var trailersRendered; + var specialFeaturesRendered; + var themeVideosRendered; + var themeSongsRendered; + + var item = options.item; var html = '
'; html += '
'; - html += '

Remote Control

'; + html += '
Remote Control
'; html += '
'; html += '
'; - html += '
'; + html += ''; + html += ''; + html += '
'; html += '
'; html += '
'; - html += '

'; - html += '

'; + html += '

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

'; html += '
'; @@ -25,11 +44,26 @@ $(document.body).append(html); - var popup = $('#remoteControlFlyout').popup({ history: false }).trigger('create').popup("open").on("popupafterclose", function () { + var popup = $('#remoteControlFlyout').popup({ history: false, tolerance: 0, corners: false }).trigger('create').popup("open").on("popupafterclose", function () { $(this).off("popupafterclose").remove(); }); + popup.on('click', '.trSession', function () { + + $('input', this).checked(true); + + + }).on('click', '.trSelectPlayTime', function () { + + $('input', this).checked(true); + + }).on('click', '.trItem', function () { + + $('input', this).checked(true); + + }); + $('#sendToForm', popup).on('submit', function () { var checkboxes = $('.chkClient', popup); @@ -64,15 +98,45 @@ ItemId: item.Id, ItemName: item.Name, ItemType: item.Type, - Context: context + Context: options.context }); } - else if (command == "Play") { + else if (command == "Play" || command == "PlayFromChapter") { + + var checkedChapter = $('.chkSelectPlayTime:checked', popup); + + var ticks = checkedChapter.length ? checkedChapter.parents('.trSelectPlayTime').attr('data-ticks') : 0; + promise = ApiClient.sendPlayCommand(sessionIds[0], { ItemIds: [item.Id].join(','), - PlayCommand: 'PlayNow' + PlayCommand: $('#fldPlayCommand', popup).val(), + StartPositionTicks: ticks + + }); + } + else if (command == "Resume") { + promise = ApiClient.sendPlayCommand(sessionIds[0], { + + ItemIds: [item.Id].join(','), + PlayCommand: 'PlayNow', + StartPositionTicks: item.UserData.PlaybackPositionTicks + + }); + } + else if (command == "Trailer" || command == "SpecialFeature" || command == "ThemeSong" || command == "ThemeVideo") { + + var id = $('.chkSelectItem:checked', popup).parents('.trItem').attr('data-id'); + + if (!id) { + Dashboard.alert('Please select an item.'); + return false; + } + promise = ApiClient.sendPlayCommand(sessionIds[0], { + + ItemIds: [id].join(','), + PlayCommand: $('#fldPlayCommand', popup).val() }); } @@ -95,12 +159,179 @@ return s.DeviceId != deviceId; }); - renderSessions(sessions, response2[0], item, elem); + renderSessions(sessions, response2[0], options, elem); + $('#selectCommand', popup).on('change', function () { + + var playFromMenu = $('.playFromMenu', popup).hide(); + var trailersElem = $('.trailers', popup).hide(); + var specialFeaturesElem = $('.specialFeatures', popup).hide(); + var themeSongsElem = $('.themeSongs', popup).hide(); + var themeVideosElem = $('.themeVideos', popup).hide(); + var playButtonContainer = $('#playButtonContainer', popup).hide(); + var queueButtonContainer = $('#queueButtonContainer', popup).hide(); + var okButtonContainer = $('#okButtonContainer', popup).hide(); + + var value = this.value; + + if (value == "Browse") { + + okButtonContainer.show(); + } + else if (value == "Play") { + + playButtonContainer.show(); + queueButtonContainer.show(); + } + else if (value == "Resume") { + + playButtonContainer.show(); + } + else if (value == "PlayFromChapter" && item.Chapters && item.Chapters.length) { + + playFromMenu.show(); + playButtonContainer.show(); + + if (!playFromRendered) { + playFromRendered = true; + renderPlayFromOptions(playFromMenu, item); + } + + $('#remoteControlFlyout').popup("reposition", { tolerance: 0 }); + } + else if (value == "Trailer") { + + trailersElem.show(); + playButtonContainer.show(); + queueButtonContainer.show(); + + if (!trailersRendered) { + trailersRendered = true; + + ApiClient.getLocalTrailers(Dashboard.getCurrentUserId(), item.Id).done(function (trailers) { + + renderVideos(trailersElem, trailers, 'Trailers'); + + $('#remoteControlFlyout').popup("reposition", { tolerance: 0 }); + }); + } + } + else if (value == "SpecialFeature") { + + specialFeaturesElem.show(); + playButtonContainer.show(); + queueButtonContainer.show(); + + if (!specialFeaturesRendered) { + specialFeaturesRendered = true; + + ApiClient.getSpecialFeatures(Dashboard.getCurrentUserId(), item.Id).done(function (videos) { + + renderVideos(specialFeaturesElem, videos, 'Special Features'); + + $('#remoteControlFlyout').popup("reposition", { tolerance: 0 }); + }); + } + } + else if (value == "ThemeSong") { + + themeSongsElem.show(); + playButtonContainer.show(); + queueButtonContainer.show(); + + if (!themeSongsRendered) { + themeSongsRendered = true; + + ApiClient.getThemeSongs(Dashboard.getCurrentUserId(), item.Id).done(function (result) { + + renderVideos(themeSongsElem, result.Items, 'Theme Songs'); + + $('#remoteControlFlyout').popup("reposition", { tolerance: 0 }); + }); + } + } + else if (value == "ThemeVideo") { + + themeVideosElem.show(); + playButtonContainer.show(); + queueButtonContainer.show(); + + if (!themeVideosRendered) { + themeVideosRendered = true; + + ApiClient.getThemeVideos(Dashboard.getCurrentUserId(), item.Id).done(function (result) { + + renderVideos(themeVideosElem, result.Items, 'Theme Videos'); + + $('#remoteControlFlyout').popup("reposition", { tolerance: 0 }); + }); + } + } + + }); }); } - function renderSessions(sessions, users, item, elem) { + function renderPlayFromOptions(elem, item) { + + var html = ''; + + html += '

Play from scene

'; + + html += '
'; + html += ''; + + html += ''; + + for (var i = 0, length = item.Chapters.length; i < length; i++) { + + var chapter = item.Chapters[i]; + + html += ''; + + var name = chapter.Name || ("Chapter " + (i + 1)); + + html += ''; + + html += ''; + + html += ''; + + html += ''; + } + + html += ''; + + html += '
'; + + var imgUrl; + + if (chapter.ImageTag) { + + imgUrl = ApiClient.getImageUrl(item.Id, { + maxheight: 80, + tag: chapter.ImageTag, + type: "Chapter", + index: i + }); + + } else { + imgUrl = "css/images/media/chapterflyout.png"; + } + + html += ''; + + html += '' + name + '
' + DashboardPage.getDisplayText(chapter.StartPositionTicks) + '
'; + html += '
'; + + elem.html(html); + + $('.tdSelectPlayTime', elem).html(''); + + $('.chkSelectPlayTime:first', elem).checked(true); + } + + function renderSessions(sessions, users, options, elem) { if (!sessions.length) { elem.html('

There are currently no available media browser sessions to control.

'); @@ -108,31 +339,63 @@ return; } + var item = options.item; + var html = ''; - html += '

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

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

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

Send To Device

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

Select Device

'; - html += ''; + html += '
'; html += ''; html += ''; html += ''; html += ''; html += ''; + html += ''; html += ''; html += ''; @@ -143,7 +406,7 @@ html += ''; - html += ''; + html += ''; html += ''; html += ''; @@ -163,6 +426,10 @@ html += ''; + html += ''; + html += ''; } @@ -170,22 +437,83 @@ html += '
ClientDeviceUserNow Playing
' + session.Client + '' + session.DeviceName + ''; + html += session.NowPlayingItem ? session.NowPlayingItem.Name : ''; + html += '
'; - html += '
'; html += '
'; elem.html(html).trigger('create'); - $('.checkboxCell', elem).html(''); + $('.tdSelectSession', elem).html(''); - $('#remoteControlFlyout').popup("reposition", {}); + $('.chkClient:first', elem).checked(true); + + $('#remoteControlFlyout').popup("reposition", { tolerance: 0 }); + } + + function renderVideos(elem, videos, header) { + + var html = ''; + + html += '

' + header + '

'; + + html += '
'; + html += ''; + + html += ''; + + for (var i = 0, length = videos.length; i < length; i++) { + + var video = videos[i]; + + html += ''; + + + html += ''; + + html += ''; + + html += ''; + + html += ''; + } + + html += ''; + + html += '
'; + + var imgUrl; + + if (video.ImageTags && video.ImageTags.Primary) { + + imgUrl = ApiClient.getImageUrl(video.Id, { + maxheight: 80, + tag: video.ImageTags.Primary, + type: "Primary" + }); + + html += ''; + } + + html += '' + video.Name; + + if (video.RunTimeTicks) { + html += '
' + DashboardPage.getDisplayText(video.RunTimeTicks); + } + + html += '
'; + html += '
'; + + elem.html(html); + + $('.tdSelectItem', elem).html(''); + + $('.chkSelectItem:first', elem).checked(true); } function remoteControl() { var self = this; - self.showMenu = function (page, item, context) { - showMenu(page, item, context, ApiClient.getSessions({ SupportsRemoteControl: true }), ApiClient.getUsers()); + self.showMenu = function (options) { + showMenu(options, ApiClient.getSessions({ SupportsRemoteControl: true }), ApiClient.getUsers()); }; }