diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index bbdb64f7a..1fe5f517a 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -20,6 +20,7 @@ - [TtheCreator](https://github.com/Tthecreator) - [RazeLighter777](https://github.com/RazeLighter777) - [LogicalPhallacy](https://github.com/LogicalPhallacy) + - [thornbill](https://github.com/thornbill) # Emby Contributors diff --git a/src/addserver.html b/src/addserver.html index f87e88950..a17bbcf72 100644 --- a/src/addserver.html +++ b/src/addserver.html @@ -3,7 +3,7 @@

${HeaderConnectToServer}

- +
${LabelServerHostHelp}

@@ -19,4 +19,4 @@
- \ No newline at end of file + diff --git a/src/availableplugins.html b/src/availableplugins.html new file mode 100644 index 000000000..ea1147fbf --- /dev/null +++ b/src/availableplugins.html @@ -0,0 +1,8 @@ +
+
+
+
${MessageNoAvailablePlugins}
+
+
+
+
\ No newline at end of file diff --git a/src/components/chromecast/chromecasthelpers.js b/src/components/chromecast/chromecasthelpers.js index c86233207..0beba824c 100644 --- a/src/components/chromecast/chromecasthelpers.js +++ b/src/components/chromecast/chromecasthelpers.js @@ -187,8 +187,13 @@ define(['events'], function (events) { return apiClient.getEndpointInfo().then(function (endpoint) { if (endpoint.IsInNetwork) { return apiClient.getPublicSystemInfo().then(function (info) { - addToCache(serverAddress, info.LocalAddress); - return info.LocalAddress; + var localAddress = info.LocalAddress + if (!localAddress) { + console.log("No valid local address returned, defaulting to external one") + localAddress = serverAddress; + } + addToCache(serverAddress, localAddress); + return localAddress; }); } else { addToCache(serverAddress, serverAddress); diff --git a/src/components/chromecast/chromecastplayer.js b/src/components/chromecast/chromecastplayer.js index d276bb4de..9b382aeec 100644 --- a/src/components/chromecast/chromecastplayer.js +++ b/src/components/chromecast/chromecastplayer.js @@ -220,7 +220,9 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' this.session = null; this.deviceState = DEVICE_STATE.IDLE; this.castPlayerState = PLAYER_STATE.IDLE; - + document.removeEventListener("volumeupbutton", onVolumeUpKeyDown, false); + document.removeEventListener("volumedownbutton", onVolumeDownKeyDown, false); + //console.log('sessionUpdateListener: setting currentMediaSession to null'); this.currentMediaSession = null; @@ -258,6 +260,9 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' this.session.addMediaListener(this.sessionMediaListener.bind(this)); this.session.addUpdateListener(this.sessionUpdateListener.bind(this)); + document.addEventListener("volumeupbutton", onVolumeUpKeyDown, false); + document.addEventListener("volumedownbutton", onVolumeDownKeyDown, false); + events.trigger(this, 'connect'); this.sendMessage({ @@ -266,6 +271,14 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }); }; + function onVolumeUpKeyDown() { + playbackManager.volumeUp(); + } + + function onVolumeDownKeyDown() { + playbackManager.volumeDown(); + } + /** * session update listener */ @@ -305,6 +318,8 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' //console.log(message); this.deviceState = DEVICE_STATE.IDLE; this.castPlayerState = PLAYER_STATE.IDLE; + document.removeEventListener("volumeupbutton", onVolumeUpKeyDown, false); + document.removeEventListener("volumedownbutton", onVolumeDownKeyDown, false); //console.log('onStopAppSuccess: setting currentMediaSession to null'); this.currentMediaSession = null; @@ -574,8 +589,15 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' events.trigger(instance, "playbackstop", [state]); + var state = instance.lastPlayerData.PlayState || {}; + var volume = state.VolumeLevel || 0.5; + var mute = state.IsMuted || false; + // Reset this so the next query doesn't make it appear like content is playing. instance.lastPlayerData = {}; + instance.lastPlayerData.PlayState = {}; + instance.lastPlayerData.PlayState.VolumeLevel = volume; + instance.lastPlayerData.PlayState.IsMuted = mute; }); events.on(instance._castPlayer, "playbackprogress", function (e, data) { @@ -780,11 +802,16 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.volumeDown = function () { + var vol = this._castPlayer.session.receiver.volume.level; + if (vol == null) + { + vol = 0.5; + } + vol -= 0.05; + vol = Math.max(vol, 0); + + this._castPlayer.session.setReceiverVolumeLevel(vol); - this._castPlayer.sendMessage({ - options: {}, - command: 'VolumeDown' - }); }; ChromecastPlayer.prototype.endSession = function () { @@ -799,24 +826,24 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }; ChromecastPlayer.prototype.volumeUp = function () { + var vol = this._castPlayer.session.receiver.volume.level; + if (vol == null) + { + vol = 0.5; + } + vol += 0.05; + vol = Math.min(vol, 1); - this._castPlayer.sendMessage({ - options: {}, - command: 'VolumeUp' - }); + this._castPlayer.session.setReceiverVolumeLevel(vol); }; ChromecastPlayer.prototype.setVolume = function (vol) { vol = Math.min(vol, 100); vol = Math.max(vol, 0); - - this._castPlayer.sendMessage({ - options: { - volume: vol - }, - command: 'SetVolume' - }); + vol = vol / 100; + + this._castPlayer.session.setReceiverVolumeLevel(vol); }; ChromecastPlayer.prototype.unpause = function () { diff --git a/src/components/notifications/badge.png b/src/components/notifications/badge.png index 372343f5c..656b51645 100644 Binary files a/src/components/notifications/badge.png and b/src/components/notifications/badge.png differ diff --git a/src/components/notifications/notificationicon.png b/src/components/notifications/notificationicon.png index 372343f5c..656b51645 100644 Binary files a/src/components/notifications/notificationicon.png and b/src/components/notifications/notificationicon.png differ diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 33b0b2b79..fedf7924b 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -1731,7 +1731,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla var maxBitrate = params.MaxStreamingBitrate || self.getMaxStreamingBitrate(player); - var currentPlayOptions = currentItem.playOptions || {}; + var currentPlayOptions = currentItem.playOptions || getDefaultPlayOptions(); getPlaybackInfo(player, apiClient, currentItem, deviceProfile, maxBitrate, ticks, true, currentMediaSource.Id, audioStreamIndex, subtitleStreamIndex, liveStreamId, params.EnableDirectPlay, params.EnableDirectStream, params.AllowVideoStreamCopy, params.AllowAudioStreamCopy).then(function (result) { @@ -2698,7 +2698,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (newItem) { - var newItemPlayOptions = newItem.playOptions || {}; + var newItemPlayOptions = newItem.playOptions || getDefaultPlayOptions(); playInternal(newItem, newItemPlayOptions, function () { setPlaylistState(newItem.PlaylistItemId, newItemIndex); @@ -2803,7 +2803,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla console.log('playing next track'); - var newItemPlayOptions = newItemInfo.item.playOptions || {}; + var newItemPlayOptions = newItemInfo.item.playOptions || getDefaultPlayOptions(); playInternal(newItemInfo.item, newItemPlayOptions, function () { setPlaylistState(newItemInfo.item.PlaylistItemId, newItemInfo.index); @@ -2826,7 +2826,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla if (newItem) { - var newItemPlayOptions = newItem.playOptions || {}; + var newItemPlayOptions = newItem.playOptions || getDefaultPlayOptions(); newItemPlayOptions.startPositionTicks = 0; playInternal(newItem, newItemPlayOptions, function () { @@ -2997,7 +2997,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla var player = this; setCurrentPlayerInternal(player); - var playOptions = item.playOptions || {}; + var playOptions = item.playOptions || getDefaultPlayOptions(); var isFirstItem = playOptions.isFirstItem; var fullscreen = playOptions.fullscreen; diff --git a/src/components/themes/logodark.png b/src/components/themes/logodark.png index 3511abc23..81a83818f 100644 Binary files a/src/components/themes/logodark.png and b/src/components/themes/logodark.png differ diff --git a/src/components/themes/logowhite.png b/src/components/themes/logowhite.png index 58f94fa98..560d910d7 100644 Binary files a/src/components/themes/logowhite.png and b/src/components/themes/logowhite.png differ diff --git a/src/controllers/addpluginpage.js b/src/controllers/addpluginpage.js index 32f71b802..0ecb65ab7 100644 --- a/src/controllers/addpluginpage.js +++ b/src/controllers/addpluginpage.js @@ -2,32 +2,40 @@ define(["jQuery", "loading", "libraryMenu", "globalize", "connectionManager", "e "use strict"; function populateHistory(packageInfo, page) { - for (var html = "", i = 0, length = Math.min(packageInfo.versions.length, 10); i < length; i++) { + var html = ""; + var length = Math.min(packageInfo.versions.length, 10); + for (var i = 0; i < length; i++) { var version = packageInfo.versions[i]; - html += '

' + version.versionStr + " (" + version.classification + ")

", html += '
' + version.description + "
" + html += '

' + version.versionStr + " (" + version.classification + ")

"; + html += '
' + version.description + "
"; } - $("#revisionHistory", page).html(html) + $("#revisionHistory", page).html(html); } function populateVersions(packageInfo, page, installedPlugin) { - for (var html = "", i = 0, length = packageInfo.versions.length; i < length; i++) { + var html = ""; + for (var i = 0; i < packageInfo.versions.length; i++) { var version = packageInfo.versions[i]; - html += '" + html += '"; } var selectmenu = $("#selectVersion", page).html(html); - installedPlugin || $("#pCurrentVersion", page).hide().html(""); + if (!installedPlugin) { + $("#pCurrentVersion", page).hide().html(""); + } var packageVersion = packageInfo.versions.filter(function(current) { - return "Release" == current.classification + return "Release" == current.classification; })[0]; - if (packageVersion || (packageVersion = packageInfo.versions.filter(function(current) { - return "Beta" == current.classification - })[0]), packageVersion) { + packageVersion = packageVersion || packageInfo.versions.filter(function(current) { + return "Beta" == current.classification; + })[0]; + + if (packageVersion) { var val = packageVersion.versionStr + "|" + packageVersion.classification; - selectmenu.val(val) + selectmenu.val(val); } } - function renderPackage(pkg, installedPlugins, pluginSecurityInfo, page) { + function renderPackage(pkg, installedPlugins, page) { var installedPlugin = installedPlugins.filter(function(ip) { return ip.Name == pkg.name })[0]; @@ -79,62 +87,69 @@ define(["jQuery", "loading", "libraryMenu", "globalize", "connectionManager", "e } function performInstallation(page, packageName, guid, updateClass, version) { - var developer = $("#developer", page).html().toLowerCase(), - alertCallback = function(confirmed) { - confirmed && (loading.show(), page.querySelector("#btnInstall").disabled = !0, ApiClient.installPlugin(packageName, guid, updateClass, version).then(function() { - loading.hide(), alertText(globalize.translate("PluginInstalledMessage")) - })) - }; - if ("luke" != developer && "ebr" != developer) { + var developer = $("#developer", page).html().toLowerCase(); + var alertCallback = function() { + loading.show(); + page.querySelector("#btnInstall").disabled = true; + ApiClient.installPlugin(packageName, guid, updateClass, version).then(function() { + loading.hide(); + alertText(globalize.translate("PluginInstalledMessage")); + }); + }; + if (developer !== 'jellyfin') { loading.hide(); var msg = globalize.translate("MessagePluginInstallDisclaimer"); - msg += "
", msg += "
", msg += globalize.translate("PleaseConfirmPluginInstallation"), require(["confirm"], function(confirm) { + msg += "
"; + msg += "
"; + msg += globalize.translate("PleaseConfirmPluginInstallation"); + require(["confirm"], function(confirm) { confirm(msg, globalize.translate("HeaderConfirmPluginInstallation")).then(function() { - alertCallback(!0) + alertCallback(); }, function() { - alertCallback(!1) - }) - }) - } else alertCallback(!0) + console.log('plugin not installed'); + }); + }); + } else { + alertCallback(); + } } + return function(view, params) { - var onSubmit = function() { + $(".addPluginForm", view).on("submit", function() { loading.show(); - var page = $(this).parents("#addPluginPage")[0], - name = params.name, - guid = params.guid; - return ApiClient.getInstalledPlugins().then(function(plugins) { - var installedPlugin = plugins.filter(function(ip) { - return ip.Name == name - })[0], - vals = $("#selectVersion", page).val().split("|"), - version = vals[0]; - installedPlugin && installedPlugin.Version == version ? (loading.hide(), Dashboard.alert({ - message: globalize.translate("MessageAlreadyInstalled"), - title: globalize.translate("HeaderPluginInstallation") - })) : performInstallation(page, name, guid, vals[1], version) - }), !1 - }; - $(".addPluginForm", view).on("submit", onSubmit), view.addEventListener("viewshow", function() { + var page = $(this).parents("#addPluginPage")[0]; + var name = params.name; + var guid = params.guid; + ApiClient.getInstalledPlugins().then(function(plugins) { + var installedPlugin = plugins.filter(function(plugin) { + return plugin.Name == name; + })[0]; + var vals = $("#selectVersion", page).val().split("|"); + var version = vals[0]; + if (installedPlugin) { + if (installedPlugin.Version === version) { + loading.hide(); + Dashboard.alert({ + message: globalize.translate("MessageAlreadyInstalled"), + title: globalize.translate("HeaderPluginInstallation") + }); + } + } else { + performInstallation(page, name, guid, vals[1], version); + } + }); + return false; + }); + view.addEventListener("viewshow", function() { var page = this; loading.show(); - var name = params.name, - guid = params.guid, - promise1 = ApiClient.getPackageInfo(name, guid), - promise2 = ApiClient.getInstalledPlugins(); - connectionManager.getRegistrationInfo("themes", ApiClient, { - viewOnly: !0 - }), Promise.all([promise1, promise2]).then(function(responses) { - connectionManager.getRegistrationInfo("themes", ApiClient, { - viewOnly: !0 - }).then(function() { - renderPackage(responses[0], responses[1], { - IsMBSupporter: !0 - }, page) - }, function() { - renderPackage(responses[0], responses[1], {}, page) - }) - }) + var name = params.name; + var guid = params.guid; + var promise1 = ApiClient.getPackageInfo(name, guid); + var promise2 = ApiClient.getInstalledPlugins(); + Promise.all([promise1, promise2]).then(function(responses) { + renderPackage(responses[0], responses[1], page); + }); }) } }); diff --git a/src/controllers/plugincatalogpage.js b/src/controllers/availableplugins.js similarity index 69% rename from src/controllers/plugincatalogpage.js rename to src/controllers/availableplugins.js index c823d7c37..62131456d 100644 --- a/src/controllers/plugincatalogpage.js +++ b/src/controllers/availableplugins.js @@ -3,7 +3,7 @@ define(["loading", "libraryMenu", "globalize", "cardStyle", "emby-button", "emby function reloadList(page) { loading.show(); - var promise1 = ApiClient.getAvailablePlugins(query); + var promise1 = ApiClient.getAvailablePlugins(); var promise2 = ApiClient.getInstalledPlugins(); Promise.all([promise1, promise2]).then(function (responses) { populateList({ @@ -33,19 +33,15 @@ define(["loading", "libraryMenu", "globalize", "cardStyle", "emby-button", "emby function populateList(options) { var availablePlugins = options.availablePlugins; var installedPlugins = options.installedPlugins; - var allPlugins = availablePlugins.filter(function (plugin) { - plugin.category = plugin.category || "General"; - plugin.categoryDisplayName = getHeaderText(plugin.category); - if (!options.categories || -1 != options.categories.indexOf(plugin.category)) { - if (!options.targetSystem || plugin.targetSystem == options.targetSystem) { - return "UserInstalled" == plugin.type; - } - } - return false; + var categories = []; + availablePlugins.forEach(function (plugin, index, array) { + plugin.category = plugin.category || 'General'; + plugin.categoryDisplayName = getHeaderText(plugin.category); + array[index] = plugin; }); - availablePlugins = allPlugins.sort(function (a, b) { + availablePlugins.sort(function (a, b) { if (a.category > b.category) { return 1; } else if (b.category > a.category) { @@ -59,45 +55,29 @@ define(["loading", "libraryMenu", "globalize", "cardStyle", "emby-button", "emby return 0; }); - var length; - var plugin; - var currentCategory; + var currentCategory = null; var html = ""; - var hasOpenTag = false; - currentCategory = null; - if (options.showCategory === false) { - html += '
'; - hasOpenTag = true; - } for (var i = 0; i < availablePlugins.length; i++) { - plugin = availablePlugins[i]; + var plugin = availablePlugins[i]; var category = plugin.categoryDisplayName; - if (category != currentCategory) { - if (false !== options.showCategory) { - if (currentCategory) { - hasOpenTag = false; - html += "
"; - html += ""; - } - html += '
'; - html += '

' + category + "

"; - html += '
'; - hasOpenTag = true; + if (currentCategory) { + html += "
"; + html += "
"; } + html += '
'; + html += '

' + category + "

"; + html += '
'; currentCategory = category; } html += getPluginHtml(plugin, options, installedPlugins); } - - if (hasOpenTag) { - html += "
"; - html += "
"; - } + html += ""; + html += ""; if (!availablePlugins.length && options.noItemsElement) { - options.noItemsElement.classList.add("hide"); + options.noItemsElement.classList.remove("hide"); } options.catalogElement.innerHTML = html; @@ -145,29 +125,19 @@ define(["loading", "libraryMenu", "globalize", "cardStyle", "emby-button", "emby function getTabs() { return [{ - href: "plugins.html", + href: "installedplugins.html", name: globalize.translate("TabMyPlugins") }, { - href: "plugincatalog.html", + href: "availableplugins.html", name: globalize.translate("TabCatalog") }]; } - var query = { - TargetSystems: "Server", - IsAppStoreSafe: true, - IsAdult: false - }; - window.PluginCatalog = { renderCatalog: populateList }; return function (view, params) { - view.querySelector("#selectSystem").addEventListener("change", function () { - query.TargetSystems = this.value; - reloadList(view); - }); view.addEventListener("viewshow", function () { libraryMenu.setTabs("plugins", 1, getTabs); reloadList(this); diff --git a/src/controllers/dashboardpage.js b/src/controllers/dashboardpage.js index 574f2e33f..33f168491 100644 --- a/src/controllers/dashboardpage.js +++ b/src/controllers/dashboardpage.js @@ -750,7 +750,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa var page = dom.parentWithClass(btn, "page"); buttonEnabled(page.querySelector("#btnRestartServer"), false); buttonEnabled(page.querySelector("#btnShutdown"), false); - Dashboard.restartServer(); + ApiClient.restartServer(); }); }); }, diff --git a/src/scripts/pluginspage.js b/src/controllers/installedplugins.js similarity index 66% rename from src/scripts/pluginspage.js rename to src/controllers/installedplugins.js index 86f49d809..40de0cc19 100644 --- a/src/scripts/pluginspage.js +++ b/src/controllers/installedplugins.js @@ -10,9 +10,10 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" primary: "cancel", confirmText: globalize.translate("UninstallPluginHeader") }).then(function() { - loading.show(), ApiClient.uninstallPlugin(uniqueid).then(function() { - reloadList(page) - }) + loading.show(); + ApiClient.uninstallPlugin(uniqueid).then(function() { + reloadList(page); + }); }) }) } @@ -20,18 +21,18 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" function showNoConfigurationMessage() { Dashboard.alert({ message: globalize.translate("NoPluginConfigurationMessage") - }) + }); } function showConnectMessage() { Dashboard.alert({ message: globalize.translate("MessagePluginConfigurationRequiresLocalAccess") - }) + }); } function getPluginCardHtml(plugin, pluginConfigurationPages) { var configPage = pluginConfigurationPages.filter(function(pluginConfigurationPage) { - return pluginConfigurationPage.PluginId == plugin.Id + return pluginConfigurationPage.PluginId == plugin.Id; })[0]; var configPageUrl = configPage ? Dashboard.getConfigurationPageUrl(configPage.Name) : null; @@ -65,38 +66,56 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" return html; } - function renderPlugins(page, plugins, showNoPluginsMessage) { + function renderPlugins(page, plugins) { ApiClient.getJSON(ApiClient.getUrl("web/configurationpages") + "?pageType=PluginConfiguration").then(function(configPages) { - populateList(page, plugins, configPages, showNoPluginsMessage) - }) + populateList(page, plugins, configPages); + }); } - function populateList(page, plugins, pluginConfigurationPages, showNoPluginsMessage) { + function populateList(page, plugins, pluginConfigurationPages) { plugins = plugins.sort(function(plugin1, plugin2) { return plugin1.Name > plugin2.Name ? 1 : -1 }); var html = plugins.map(function(p) { return getPluginCardHtml(p, pluginConfigurationPages) - }).join(""), - installedPluginsElement = page.querySelector(".installedPlugins"); - installedPluginsElement.removeEventListener("click", onInstalledPluginsClick), installedPluginsElement.addEventListener("click", onInstalledPluginsClick), plugins.length ? (installedPluginsElement.classList.add("itemsContainer"), installedPluginsElement.classList.add("vertical-wrap"), installedPluginsElement.innerHTML = html) : (showNoPluginsMessage && (html += '
', html += "

" + globalize.translate("MessageNoPluginsInstalled") + "

", html += '

', html += globalize.translate("BrowsePluginCatalogMessage"), html += "

", html += "
"), installedPluginsElement.innerHTML = html), loading.hide() + }).join(""); + var installedPluginsElement = page.querySelector(".installedPlugins"); + installedPluginsElement.removeEventListener("click", onInstalledPluginsClick); + installedPluginsElement.addEventListener("click", onInstalledPluginsClick); + if (plugins.length) { + installedPluginsElement.classList.add("itemsContainer"); + installedPluginsElement.classList.add("vertical-wrap"); + } else { + html += '
'; + html += "

" + globalize.translate("MessageNoPluginsInstalled") + "

"; + html += '

'; + html += globalize.translate("BrowsePluginCatalogMessage"); + html += "

"; + html += "
"; + } + installedPluginsElement.innerHTML = html; + loading.hide(); } function showPluginMenu(page, elem) { - var card = dom.parentWithClass(elem, "card"), - id = card.getAttribute("data-id"), - name = card.getAttribute("data-name"), - configHref = card.querySelector(".cardContent").getAttribute("href"), - menuItems = []; - configHref && menuItems.push({ - name: globalize.translate("ButtonSettings"), - id: "open", - ironIcon: "mode-edit" - }), menuItems.push({ + var card = dom.parentWithClass(elem, "card"); + var id = card.getAttribute("data-id"); + var name = card.getAttribute("data-name"); + var configHref = card.querySelector(".cardContent").getAttribute("href"); + var menuItems = []; + if (configHref) { + menuItems.push({ + name: globalize.translate("ButtonSettings"), + id: "open", + ironIcon: "mode-edit" + }); + } + menuItems.push({ name: globalize.translate("ButtonUninstall"), id: "delete", ironIcon: "delete" - }), require(["actionsheet"], function(actionsheet) { + }); + require(["actionsheet"], function(actionsheet) { actionsheet.show({ items: menuItems, positionTo: elem, @@ -109,37 +128,44 @@ define(["loading", "libraryMenu", "dom", "globalize", "cardStyle", "emby-button" deletePlugin(page, id, name) } } - }) - }) + }); + }); } function reloadList(page) { - loading.show(), ApiClient.getInstalledPlugins().then(function(plugins) { - renderPlugins(page, plugins, !0) - }) + loading.show(); + ApiClient.getInstalledPlugins().then(function(plugins) { + renderPlugins(page, plugins); + }); } function getTabs() { return [{ - href: "plugins.html", + href: "installedplugins.html", name: globalize.translate("TabMyPlugins") }, { - href: "plugincatalog.html", + href: "availableplugins.html", name: globalize.translate("TabCatalog") }] } function onInstalledPluginsClick(e) { - if (dom.parentWithClass(e.target, "noConfigPluginCard")) showNoConfigurationMessage(); - else if (dom.parentWithClass(e.target, "connectModePluginCard")) showConnectMessage(); - else { + if (dom.parentWithClass(e.target, "noConfigPluginCard")) { + showNoConfigurationMessage(); + } else if (dom.parentWithClass(e.target, "connectModePluginCard")) { + showConnectMessage(); + } else { var btnCardMenu = dom.parentWithClass(e.target, "btnCardMenu"); - btnCardMenu && showPluginMenu(dom.parentWithClass(btnCardMenu, "page"), btnCardMenu) + btnCardMenu && showPluginMenu(dom.parentWithClass(btnCardMenu, "page"), btnCardMenu); } } + pageIdOn("pageshow", "pluginsPage", function() { - libraryMenu.setTabs("plugins", 0, getTabs), reloadList(this) - }), window.PluginsPage = { + libraryMenu.setTabs("plugins", 0, getTabs); + reloadList(this); + }); + + window.PluginsPage = { renderPlugins: renderPlugins } }); diff --git a/src/controllers/loginpage.js b/src/controllers/loginpage.js index fc8369c29..2f396ff5e 100644 --- a/src/controllers/loginpage.js +++ b/src/controllers/loginpage.js @@ -1,91 +1,148 @@ -define(["appSettings", "dom", "connectionManager", "loading", "cardStyle", "emby-checkbox"], function(appSettings, dom, connectionManager, loading) { +define(["apphost", "appSettings", "dom", "connectionManager", "loading", "cardStyle", "emby-checkbox"], function(appHost, appSettings, dom, connectionManager, loading) { "use strict"; function authenticateUserByName(page, apiClient, username, password) { - loading.show(), apiClient.authenticateUserByName(username, password).then(function(result) { - var newUrl, user = result.User, - serverId = getParameterByName("serverid"); - newUrl = user.Policy.IsAdministrator && !serverId ? "dashboard.html" : "home.html", loading.hide(), Dashboard.onServerChanged(user.Id, result.AccessToken, apiClient), Dashboard.navigate(newUrl) + loading.show(); + apiClient.authenticateUserByName(username, password).then(function(result) { + var user = result.User; + var serverId = getParameterByName("serverid"); + var newUrl = user.Policy.IsAdministrator && !serverId ? "dashboard.html" : "home.html"; + loading.hide(); + Dashboard.onServerChanged(user.Id, result.AccessToken, apiClient); + Dashboard.navigate(newUrl); }, function(response) { - page.querySelector("#txtManualName").value = "", page.querySelector("#txtManualPassword").value = "", loading.hide(), 401 == response.status ? require(["toast"], function(toast) { - toast(Globalize.translate("MessageInvalidUser")) - }) : showServerConnectionFailure() - }) - } - - function showServerConnectionFailure() { - Dashboard.alert({ - message: Globalize.translate("MessageUnableToConnectToServer"), - title: Globalize.translate("HeaderConnectionFailure") - }) + page.querySelector("#txtManualName").value = ""; + page.querySelector("#txtManualPassword").value = ""; + loading.hide(); + if (response.status === 401) { + require(["toast"], function(toast) { + toast(Globalize.translate("MessageInvalidUser")); + }); + } else { + Dashboard.alert({ + message: Globalize.translate("MessageUnableToConnectToServer"), + title: Globalize.translate("HeaderConnectionFailure") + }); + } + }); } function showManualForm(context, showCancel, focusPassword) { - context.querySelector(".chkRememberLogin").checked = appSettings.enableAutoLogin(), context.querySelector(".manualLoginForm").classList.remove("hide"), context.querySelector(".visualLoginForm").classList.add("hide"), focusPassword ? context.querySelector("#txtManualPassword").focus() : context.querySelector("#txtManualName").focus(), showCancel ? context.querySelector(".btnCancel").classList.remove("hide") : context.querySelector(".btnCancel").classList.add("hide") + context.querySelector(".chkRememberLogin").checked = appSettings.enableAutoLogin(); + context.querySelector(".manualLoginForm").classList.remove("hide"); + context.querySelector(".visualLoginForm").classList.add("hide"); + focusPassword ? context.querySelector("#txtManualPassword").focus() : context.querySelector("#txtManualName").focus(); + showCancel ? context.querySelector(".btnCancel").classList.remove("hide") : context.querySelector(".btnCancel").classList.add("hide"); } + var metroColors = ["#6FBD45", "#4BB3DD", "#4164A5", "#E12026", "#800080", "#E1B222", "#008040", "#0094FF", "#FF00C7", "#FF870F", "#7F0037"]; + function getRandomMetroColor() { var index = Math.floor(Math.random() * (metroColors.length - 1)); - return metroColors[index] + return metroColors[index]; } function getMetroColor(str) { if (str) { - for (var character = String(str.substr(0, 1).charCodeAt()), sum = 0, i = 0; i < character.length; i++) sum += parseInt(character.charAt(i)); + var character = String(str.substr(0, 1).charCodeAt()); + var sum = 0; + for (var i = 0; i < character.length; i++) { + sum += parseInt(character.charAt(i)); + } var index = String(sum).substr(-1); - return metroColors[index] + return metroColors[index]; } - return getRandomMetroColor() + return getRandomMetroColor(); } function loadUserList(context, apiClient, users) { - for (var html = "", i = 0, length = users.length; i < length; i++) { + var html = ""; + for (var i = 0; i < users.length; i++) { var user = users[i]; - html += '" + html += ""; + html += ""; + html += '
'; + html += '
' + user.Name + "
"; + html += "
"; + html += ""; + html += ""; } - context.querySelector("#divUsers").innerHTML = html + context.querySelector("#divUsers").innerHTML = html; } - var metroColors = ["#6FBD45", "#4BB3DD", "#4164A5", "#E12026", "#800080", "#E1B222", "#008040", "#0094FF", "#FF00C7", "#FF870F", "#7F0037"]; + return function(view, params) { function getApiClient() { var serverId = params.serverid; - return serverId ? connectionManager.getOrCreateApiClient(serverId) : ApiClient + return serverId ? connectionManager.getOrCreateApiClient(serverId) : ApiClient; } function showVisualForm() { - view.querySelector(".visualLoginForm").classList.remove("hide"), view.querySelector(".manualLoginForm").classList.add("hide") + view.querySelector(".visualLoginForm").classList.remove("hide"); + view.querySelector(".manualLoginForm").classList.add("hide"); } + view.querySelector("#divUsers").addEventListener("click", function(e) { - var card = dom.parentWithClass(e.target, "card"), - cardContent = card ? card.querySelector(".cardContent") : null; + var card = dom.parentWithClass(e.target, "card"); + var cardContent = card ? card.querySelector(".cardContent") : null; if (cardContent) { - var context = view, - id = cardContent.getAttribute("data-userid"), - name = cardContent.getAttribute("data-username"), - haspw = cardContent.getAttribute("data-haspw"); - "manual" == id ? (context.querySelector("#txtManualName").value = "", showManualForm(context, !0)) : "false" == haspw ? authenticateUserByName(context, getApiClient(), name, "") : (context.querySelector("#txtManualName").value = name, context.querySelector("#txtManualPassword").value = "", showManualForm(context, !0, !0)) + var context = view; + var id = cardContent.getAttribute("data-userid"); + var name = cardContent.getAttribute("data-username"); + var haspw = cardContent.getAttribute("data-haspw"); + if (id === 'manual') { + context.querySelector("#txtManualName").value = ""; + showManualForm(context, true); + } else if (haspw == 'false') { + authenticateUserByName(context, getApiClient(), name, ""); + } else { + context.querySelector("#txtManualName").value = name; + context.querySelector("#txtManualPassword").value = ""; + showManualForm(context, true, true); + } } - }), view.querySelector(".manualLoginForm").addEventListener("submit", function(e) { + }); + + view.querySelector(".manualLoginForm").addEventListener("submit", function(e) { appSettings.enableAutoLogin(view.querySelector(".chkRememberLogin").checked); var apiClient = getApiClient(); - return authenticateUserByName(view, apiClient, view.querySelector("#txtManualName").value, view.querySelector("#txtManualPassword").value), e.preventDefault(), !1 - }), view.querySelector(".btnForgotPassword").addEventListener("click", function() { - Dashboard.navigate("forgotpassword.html") - }), view.querySelector(".btnCancel").addEventListener("click", showVisualForm), view.querySelector(".btnManual").addEventListener("click", function() { - view.querySelector("#txtManualName").value = "", showManualForm(view, !0) - }), view.addEventListener("viewshow", function(e) { + authenticateUserByName(view, apiClient, view.querySelector("#txtManualName").value, view.querySelector("#txtManualPassword").value); + e.preventDefault(); + return false; + }); + + view.querySelector(".btnForgotPassword").addEventListener("click", function() { + Dashboard.navigate("forgotpassword.html"); + }); + + view.querySelector(".btnCancel").addEventListener("click", showVisualForm); + + view.querySelector(".btnManual").addEventListener("click", function() { + view.querySelector("#txtManualName").value = ""; + showManualForm(view, true); + }); + + view.addEventListener("viewshow", function(e) { loading.show(); + if (!appHost.supports('multiserver')) { + view.querySelector(".btnSelectServer").classList.add("hide"); + } var apiClient = getApiClient(); apiClient.getPublicUsers().then(function(users) { if (users.length) { @@ -105,7 +162,7 @@ define(["appSettings", "dom", "connectionManager", "loading", "cardStyle", "emby }); apiClient.getJSON(apiClient.getUrl("Branding/Configuration")).then(function(options) { - view.querySelector(".disclaimer").textContent = options.LoginDisclaimer || "" + view.querySelector(".disclaimer").textContent = options.LoginDisclaimer || ""; }); }); } diff --git a/src/css/site.css b/src/css/site.css index 0111b3823..f048f4b8f 100644 --- a/src/css/site.css +++ b/src/css/site.css @@ -74,7 +74,8 @@ div[data-role=page] { .padded-bottom-page, .page, .pageWithAbsoluteTabs .pageTabContent { - padding-bottom: 2em !important + /* provides room for the music controls */ + padding-bottom: 5em !important } @media all and (min-width:50em) { diff --git a/src/edititemmetadata.html b/src/edititemmetadata.html index adfd3568f..86712a24f 100644 --- a/src/edititemmetadata.html +++ b/src/edititemmetadata.html @@ -1,4 +1,4 @@ -
+