diff --git a/dashboard-ui/scripts/actionsheet.js b/dashboard-ui/scripts/actionsheet.js index 2a129a30c1..d167ed665b 100644 --- a/dashboard-ui/scripts/actionsheet.js +++ b/dashboard-ui/scripts/actionsheet.js @@ -5,7 +5,7 @@ } function show(options) { - require(['paperbuttonstyle'], function() { + require(['paperbuttonstyle'], function () { // items // positionTo // showCancel @@ -13,7 +13,39 @@ var id = 'dlg' + new Date().getTime(); var html = ''; - html += ''; + var style = ""; + + if (options.positionTo) { + + var pos = $(options.positionTo).offset(); + + pos.top += $(options.positionTo).innerHeight() / 2; + pos.left += $(options.positionTo).innerWidth() / 2; + + // Account for margins + pos.top -= 24; + pos.left -= 24; + + // Account for popup size - we can't predict this yet so just estimate + pos.top -= 100; + pos.left -= 80; + + // Account for scroll position + pos.top -= $(window).scrollTop(); + pos.left -= $(window).scrollLeft(); + + // Avoid showing too close to the bottom + pos.top = Math.min(pos.top, $(window).height() - 300); + pos.left = Math.min(pos.left, $(window).width() - 300); + + // Do some boundary checking + pos.top = Math.max(pos.top, 0); + pos.left = Math.max(pos.left, 0); + + style += 'position:fixed;top:' + pos.top + 'px;left:' + pos.left + 'px'; + } + + html += ''; if (options.title) { html += '

'; @@ -26,8 +58,11 @@ var option = options.items[i]; - html += ''; - //html += ''; + html += ''; + + if (option.ironIcon) { + html += ''; + } html += '' + option.name + ''; html += ''; } @@ -53,10 +88,18 @@ $('.btnOption', dlg).on('click', function () { - if (options.callback) { - options.callback(this.getAttribute('data-id')); - } - dlg.close(); + var selectedId = this.getAttribute('data-id'); + + // Add a delay here to allow the click animation to finish, for nice effect + setTimeout(function () { + + dlg.close(); + + if (options.callback) { + options.callback(selectedId); + } + + }, 100); }); }, 100); }); diff --git a/dashboard-ui/scripts/addpluginpage.js b/dashboard-ui/scripts/addpluginpage.js index 6c6e090517..eda1ca9c0b 100644 --- a/dashboard-ui/scripts/addpluginpage.js +++ b/dashboard-ui/scripts/addpluginpage.js @@ -17,6 +17,7 @@ } function populateVersions(packageInfo, page, installedPlugin) { + var html = ''; for (var i = 0, length = packageInfo.versions.length; i < length; i++) { @@ -109,12 +110,12 @@ $('.pluginName', page).html(pkg.name); if (pkg.targetSystem == 'Server') { - $("#btnInstallDiv", page).show(); + $("#btnInstallDiv", page).visible(true); $("#nonServerMsg", page).hide(); - $("#pSelectVersion", page).show(); + $("#pSelectVersion", page).visible(true); } else { - $("#btnInstallDiv", page).hide(); - $("#pSelectVersion", page).hide(); + $("#btnInstallDiv", page).visible(false); + $("#pSelectVersion", page).visible(false); var msg = Globalize.translate('MessageInstallPluginFromApp'); $("#nonServerMsg", page).html(msg).show(); diff --git a/dashboard-ui/scripts/itembynamedetailpage.js b/dashboard-ui/scripts/itembynamedetailpage.js index 8796b9edfc..8f3e42c26e 100644 --- a/dashboard-ui/scripts/itembynamedetailpage.js +++ b/dashboard-ui/scripts/itembynamedetailpage.js @@ -557,7 +557,7 @@ $('.btnPlay', page).on('click', function () { var userdata = currentItem.UserData || {}; - LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, false, "Audio", userdata.PlaybackPositionTicks); + LibraryBrowser.showPlayMenu(null, currentItem.Id, currentItem.Type, false, "Audio", userdata.PlaybackPositionTicks); }); $('.itemsContainer', page).on('playallfromhere', function (e, index) { diff --git a/dashboard-ui/scripts/itemdetailpage.js b/dashboard-ui/scripts/itemdetailpage.js index 6af94ec863..dcfe93b172 100644 --- a/dashboard-ui/scripts/itemdetailpage.js +++ b/dashboard-ui/scripts/itemdetailpage.js @@ -1588,7 +1588,7 @@ mediaType = "Audio"; } - LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, currentItem.IsFolder, mediaType, userdata.PlaybackPositionTicks); + LibraryBrowser.showPlayMenu(null, currentItem.Id, currentItem.Type, currentItem.IsFolder, mediaType, userdata.PlaybackPositionTicks); }); $('.btnPlayTrailer', page).on('click', function () { diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index 2284a6aea7..85018e8c47 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -237,7 +237,7 @@ }); }, - showPlayMenu: function (positionTo, itemId, itemType, isFolder, mediaType, resumePositionTicks, showAddToPlaylist) { + showPlayMenu: function (positionTo, itemId, itemType, isFolder, mediaType, resumePositionTicks) { var externalPlayers = AppSettings.enableExternalPlayers(); @@ -249,49 +249,91 @@ } } - $('.playFlyout').popup("close").remove(); - - var html = '
'; - - html += ''; + ActionSheetElement.show({ + items: menuItems, + positionTo: positionTo, + callback: function (id) { - html += '
'; + switch (id) { - $($.mobile.activePage).append(html); + case 'play': + MediaController.play(itemId); + break; + case 'externalplayer': + LibraryBrowser.playInExternalPlayer(itemId); + break; + case 'resume': + MediaController.play({ + ids: [itemId], + startPositionTicks: resumePositionTicks + }); + break; + case 'queue': + MediaController.queue(itemId); + break; + case 'instantmix': + MediaController.instantMix(itemId); + break; + case 'shuffle': + MediaController.shuffle(itemId); + break; + default: + break; + } + } + }); - $('.playFlyout').popup({ positionTo: positionTo || "window" }).trigger('create').popup("open").on("popupafterclose", function () { - - $(this).off("popupafterclose").remove(); - - }).parents(".ui-popup-container"); + }); }, closePlayMenu: function () { @@ -357,7 +399,7 @@ // The timeout allows the flyout to close setTimeout(function () { - var msg = "

" + Globalize.translate('ConfirmDeleteItem') + "

"; + var msg = Globalize.translate('ConfirmDeleteItem'); Dashboard.confirm(msg, Globalize.translate('HeaderDeleteItem'), function (result) { @@ -426,10 +468,10 @@ switch (id) { case 'addtocollection': - BoxSetEditor.showPanel(itemId); + BoxSetEditor.showPanel([itemId]); break; - case 'icon': - PlaylistManager.showPanel(itemId); + case 'playlist': + PlaylistManager.showPanel([itemId]); break; case 'delete': LibraryBrowser.deleteItem(itemId); diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js index 3d2a6898fa..6faf7e0a93 100644 --- a/dashboard-ui/scripts/librarylist.js +++ b/dashboard-ui/scripts/librarylist.js @@ -1006,7 +1006,7 @@ msg += "

" + Globalize.translate('MessageConfirmItemGrouping'); - Dashboard.confirm(msg, "Group Versions", function (confirmResult) { + Dashboard.confirm(msg, Globalize.translate('HeaderGroupVersions'), function (confirmResult) { if (confirmResult) { diff --git a/dashboard-ui/scripts/livetvchannel.js b/dashboard-ui/scripts/livetvchannel.js index bf286af509..ebbca9b4d5 100644 --- a/dashboard-ui/scripts/livetvchannel.js +++ b/dashboard-ui/scripts/livetvchannel.js @@ -168,7 +168,7 @@ $('#btnPlay', page).on('click', function () { var userdata = currentItem.UserData || {}; - LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, false, currentItem.MediaType, userdata.PlaybackPositionTicks); + LibraryBrowser.showPlayMenu(null, currentItem.Id, currentItem.Type, false, currentItem.MediaType, userdata.PlaybackPositionTicks); }); $('#btnEdit', page).on('click', function () { diff --git a/dashboard-ui/scripts/livetvguide.js b/dashboard-ui/scripts/livetvguide.js index 659d0159ff..29cadb03d8 100644 --- a/dashboard-ui/scripts/livetvguide.js +++ b/dashboard-ui/scripts/livetvguide.js @@ -378,7 +378,8 @@ dateOptions.push({ name: LibraryBrowser.getFutureDateText(start), - id: start.getTime() + id: start.getTime(), + ironIcon: 'today' }); start.setDate(start.getDate() + 1); diff --git a/dashboard-ui/scripts/livetvprogram.js b/dashboard-ui/scripts/livetvprogram.js index 0ac8499a46..7df553ce31 100644 --- a/dashboard-ui/scripts/livetvprogram.js +++ b/dashboard-ui/scripts/livetvprogram.js @@ -112,7 +112,7 @@ var userdata = channel.UserData || {}; - LibraryBrowser.showPlayMenu(this, channel.Id, channel.Type, false, channel.MediaType, userdata.PlaybackPositionTicks); + LibraryBrowser.showPlayMenu(null, channel.Id, channel.Type, false, channel.MediaType, userdata.PlaybackPositionTicks); }); }); diff --git a/dashboard-ui/scripts/livetvrecording.js b/dashboard-ui/scripts/livetvrecording.js index 29aecfb05a..cb9ec7c1c5 100644 --- a/dashboard-ui/scripts/livetvrecording.js +++ b/dashboard-ui/scripts/livetvrecording.js @@ -27,7 +27,7 @@ var mediaType = currentItem.MediaType; - LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, false, mediaType, userdata.PlaybackPositionTicks); + LibraryBrowser.showPlayMenu(null, currentItem.Id, currentItem.Type, false, mediaType, userdata.PlaybackPositionTicks); } function renderRecording(page, item) { diff --git a/dashboard-ui/scripts/playlistedit.js b/dashboard-ui/scripts/playlistedit.js index c3517ce2ae..cc80e93207 100644 --- a/dashboard-ui/scripts/playlistedit.js +++ b/dashboard-ui/scripts/playlistedit.js @@ -187,7 +187,7 @@ mediaType = "Audio"; } - LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.Type, currentItem.IsFolder, mediaType, userdata.PlaybackPositionTicks); + LibraryBrowser.showPlayMenu(null, currentItem.Id, currentItem.Type, currentItem.IsFolder, mediaType, userdata.PlaybackPositionTicks); }); $('.itemsContainer', page).on('needsrefresh', function () { diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index b553f64e55..9576576951 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -50,7 +50,9 @@ var Dashboard = { $.event.special.swipe.verticalDistanceThreshold = 40; $.mobile.loader.prototype.options.disabled = true; - //$.mobile.page.prototype.options.domCache = true; + + + $.mobile.page.prototype.options.domCache = true; $.mobile.loadingMessage = false; $.mobile.loader.prototype.options.html = ""; @@ -570,7 +572,7 @@ var Dashboard = { confirm: function (message, title, callback) { // Cordova - if (navigator.notification && navigator.notification.alert && message.indexOf('<') == -1) { + if (navigator.notification && navigator.notification.confirm && message.indexOf('<') == -1) { var buttonLabels = [Globalize.translate('ButtonOk'), Globalize.translate('ButtonCancel')]; diff --git a/dashboard-ui/thirdparty/cordova/imagestore.js b/dashboard-ui/thirdparty/cordova/imagestore.js index effc581a67..449f13f2f5 100644 --- a/dashboard-ui/thirdparty/cordova/imagestore.js +++ b/dashboard-ui/thirdparty/cordova/imagestore.js @@ -54,7 +54,9 @@ function normalizeReturnUrl(url) { if ($.browser.safari) { - if ($.browser.iOSVersion == 8) { + // Use the embedded server for iOS8, and also if we don't know the iOS version, just to be safe + //if ($.browser.iOSVersion == 8 || !$.browser.iOSVersion) + { return url.replace('file://', ''); } } diff --git a/dashboard-ui/thirdparty/cordova/ios/actionsheet.js b/dashboard-ui/thirdparty/cordova/ios/actionsheet.js index 3a955b534b..63d6a67fd0 100644 --- a/dashboard-ui/thirdparty/cordova/ios/actionsheet.js +++ b/dashboard-ui/thirdparty/cordova/ios/actionsheet.js @@ -14,7 +14,8 @@ }) }; - if (options.showCancel) { + // Show cancel unless the caller explicitly set it to false + if (options.showCancel !== false) { innerOptions.addCancelButtonWithLabel = Globalize.translate('ButtonCancel'); } diff --git a/dashboard-ui/thirdparty/emby-icons.html b/dashboard-ui/thirdparty/emby-icons.html index 8e328be6a8..fcb967c220 100644 --- a/dashboard-ui/thirdparty/emby-icons.html +++ b/dashboard-ui/thirdparty/emby-icons.html @@ -34,24 +34,30 @@ See [iron-iconset](#iron-iconset) and [iron-iconset-svg](#iron-iconset-svg) for - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dashboard-ui/thirdparty/paper-button-style.css b/dashboard-ui/thirdparty/paper-button-style.css index c84fc5c911..ec597d2ac1 100644 --- a/dashboard-ui/thirdparty/paper-button-style.css +++ b/dashboard-ui/thirdparty/paper-button-style.css @@ -17,6 +17,15 @@ background: #e1f5f3; } + paper-button.menuButton { + color: #212121; + text-align: left; + } + + paper-button.menuButton:hover { + background: #e1f5f3; + } + paper-button.ripple::shadow paper-ripple { color: #ff3bee; } @@ -185,6 +194,23 @@ paper-button.notext { bottom: 30px; } +paper-dialog { + border-radius: 4px; +} + iron-overlay-backdrop { z-index: 999998 !important; } + +/* These values default to 24px and create huge white padding around the dialog content. */ +.scrollable.paper-dialog-scrollable { + padding: 0 12px; +} + +paper-dialog > *:last-child { + margin-bottom: 12px; +} + +paper-dialog > *:first-child { + margin-top: 12px; +}