diff --git a/dashboard-ui/css/site.css b/dashboard-ui/css/site.css index 34d3bf17f2..3c3714f548 100644 --- a/dashboard-ui/css/site.css +++ b/dashboard-ui/css/site.css @@ -346,7 +346,7 @@ h1 .imageLink { } .dashboardPanelLink { - padding: .5em .5em .5em 1.25em; + padding: .6em .5em .6em 1.25em; display: block; text-decoration: none; color: #fff!important; diff --git a/dashboard-ui/login.html b/dashboard-ui/login.html index f1d65b3bf0..7394b7f91a 100644 --- a/dashboard-ui/login.html +++ b/dashboard-ui/login.html @@ -21,6 +21,12 @@ ${ButtonSignIn}

+ +

+ +

'; return itemHtml; diff --git a/dashboard-ui/scripts/directorybrowser.js b/dashboard-ui/scripts/directorybrowser.js index 897ea344bf..4c6334857a 100644 --- a/dashboard-ui/scripts/directorybrowser.js +++ b/dashboard-ui/scripts/directorybrowser.js @@ -113,11 +113,11 @@ html += '
'; html += ''; - html += '
'; + html += '
'; html += ''; html += '
'; - html += '
'; + html += '
'; html += ''; diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index 216f4d9a8d..81d5020cd2 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -595,13 +595,15 @@ if (item.ImageTags.Primary) { // Scaling 400w episode images to 80 doesn't turn out very well - var width = item.Type == 'Episode' || item.Type == 'Game' ? 160 : 80; + var minScale = item.Type == 'Episode' || item.Type == 'Game' ? 2 : null; imgUrl = ApiClient.getScaledImageUrl(item.Id, { - width: width, + width: 80, tag: item.ImageTags.Primary, type: "Primary", - index: 0 + index: 0, + EnableImageEnhancers: false, + minScale: minScale }); } @@ -649,7 +651,7 @@ if (item.UserData.UnplayedItemCount) { html += '' + item.UserData.UnplayedItemCount + ''; } - else if (item.UserData.Played) { + else if (item.UserData.Played && item.Type != 'TvChannel') { html += '
'; } } @@ -1306,8 +1308,10 @@ return '
' + item.UserData.UnplayedItemCount + '
'; } - if (item.UserData.PlayedPercentage >= 100 || (item.UserData && item.UserData.Played)) { - return '
'; + if (item.Type != 'TvChannel') { + if (item.UserData.PlayedPercentage >= 100 || (item.UserData && item.UserData.Played)) { + return '
'; + } } } diff --git a/dashboard-ui/scripts/loginpage.js b/dashboard-ui/scripts/loginpage.js index aeddca1d4d..0e7ba48100 100644 --- a/dashboard-ui/scripts/loginpage.js +++ b/dashboard-ui/scripts/loginpage.js @@ -6,25 +6,22 @@ var page = this; - var location = window.location.toString().toLowerCase(); - var isLocalhost = location.indexOf('localhost') != -1 || location.indexOf('127.0.0.1') != -1; - - if (isLocalhost) { + if (LoginPage.isLocalhost()) { $('.localhostMessage', page).show(); } else { $('.localhostMessage', page).hide(); } // Show all users on localhost - var promise1 = !isLocalhost ? ApiClient.getPublicUsers() : ApiClient.getUsers({ IsDisabled: false }); + var promise1 = ApiClient.getPublicUsers(); promise1.done(function (users) { - var showManualForm = !users.length || !isLocalhost; + var showManualForm = !users.length; if (showManualForm) { - LoginPage.showManualForm(page); + LoginPage.showManualForm(page, false); } else { LoginPage.showVisualForm(page); @@ -40,10 +37,27 @@ }); }, - showManualForm: function (page) { + isLocalhost: function () { + + var location = window.location.toString().toLowerCase(); + return location.indexOf('localhost') != -1 || location.indexOf('127.0.0.1') != -1; + }, + + cancelLogin: function() { + + LoginPage.showVisualForm($.mobile.activePage); + }, + + showManualForm: function (page, showCancel) { $('.visualLoginForm', page).hide(); $('#manualLoginForm', page).show(); $('#txtManualName', page).focus(); + + if (showCancel) { + $('.btnCancel', page).show(); + } else { + $('.btnCancel', page).hide(); + } }, showVisualForm: function (page) { @@ -73,22 +87,6 @@ }); }, - authenticateUserLink: function (link) { - - LoginPage.authenticateUser(link.getAttribute('data-userid')); - }, - - authenticateUser: function (userId, password) { - - Dashboard.showLoadingMsg(); - - ApiClient.getUser(userId).done(function (user) { - - LoginPage.authenticateUserByName(user.Name, password); - }); - - }, - authenticateUserByName: function (username, password) { Dashboard.showLoadingMsg(); @@ -97,12 +95,12 @@ var user = result.User; - Dashboard.setCurrentUser(user.Id); + Dashboard.setCurrentUser(user.Id, result.AccessToken); if (user.Configuration.IsAdministrator) { - window.location = "dashboard.html?u=" + user.Id; + window.location = "dashboard.html?u=" + user.Id + '&t=' + result.AccessToken; } else { - window.location = "index.html?u=" + user.Id; + window.location = "index.html?u=" + user.Id + '&t=' + result.AccessToken; } }).fail(function () { @@ -123,12 +121,14 @@ loadUserList: function (users) { var html = ""; + var page = $.mobile.activePage; + for (var i = 0, length = users.length; i < length; i++) { var user = users[i]; var linkId = "lnkUser" + i; - html += ""; + html += ""; if (user.PrimaryImageTag) { @@ -162,8 +162,21 @@ html += ''; } - $('#divUsers', '#loginPage').html(html); + var elem = $('#divUsers', '#loginPage').html(html); + $('.posterItem', elem).on('click', function () { + + var name = this.getAttribute('data-username'); + var haspw = this.getAttribute('data-haspw'); + + if (LoginPage.isLocalhost() || haspw == 'false') { + LoginPage.authenticateUserByName(name, ''); + } else { + $('#txtManualName', page).val(name); + $('#txtManualPassword', '#loginPage').val(''); + LoginPage.showManualForm(page, true); + } + }); }, onManualSubmit: function () { diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index b555dc4e62..b4dbc8804c 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -68,6 +68,11 @@ var Dashboard = { } }, + getAccessToken: function () { + + return localStorage.getItem('token'); + }, + getCurrentUserId: function () { if (!window.localStorage) { @@ -76,24 +81,24 @@ var Dashboard = { var autoLoginUserId = getParameterByName('u'); var storedUserId = localStorage.getItem("userId"); - var userId; if (autoLoginUserId && autoLoginUserId != storedUserId) { - localStorage.setItem("userId", autoLoginUserId); - ApiClient.currentUserId(autoLoginUserId); + var token = getParameterByName('t'); + Dashboard.setCurrentUser(autoLoginUserId, token); } return autoLoginUserId || storedUserId; }, - setCurrentUser: function (userId) { + setCurrentUser: function (userId, token) { if (window.localStorage) { localStorage.setItem("userId", userId); + localStorage.setItem("token", token); } - ApiClient.currentUserId(userId); + ApiClient.setCurrentUserId(userId, token); Dashboard.getUserPromise = null; }, @@ -101,11 +106,12 @@ var Dashboard = { if (window.localStorage) { localStorage.removeItem("userId"); + localStorage.removeItem("token"); } - Dashboard.getUserPromise = null; - ApiClient.currentUserId(null); - window.location = "login.html"; + ApiClient.logout().done(function () { + window.location = "login.html"; + }); }, showError: function (message) { @@ -146,6 +152,7 @@ var Dashboard = { updateSystemInfo: function (info) { Dashboard.lastSystemInfo = info; + Dashboard.ensureWebSocket(info); if (!Dashboard.initialServerVersion) { @@ -403,10 +410,14 @@ var Dashboard = { }, refreshSystemInfoFromServer: function () { - ApiClient.getSystemInfo().done(function (info) { - Dashboard.updateSystemInfo(info); - }); + // TODO: Eventually remove the currentUserId check + if (Dashboard.getAccessToken() || Dashboard.getCurrentUserId()) { + ApiClient.getSystemInfo().done(function (info) { + + Dashboard.updateSystemInfo(info); + }); + } }, restartServer: function () { @@ -649,6 +660,10 @@ var Dashboard = { name: "Dashboard", href: "dashboard.html", selected: page.hasClass("dashboardHomePage") + }, { + name: "Users", + href: "userprofiles.html", + selected: page.hasClass("userProfilesConfigurationPage") || (pageElem.id == "mediaLibraryPage" && getParameterByName('userId')) }, { name: "Library", divider: true, @@ -679,11 +694,6 @@ var Dashboard = { name: "Plugins", href: "plugins.html", selected: page.hasClass("pluginConfigurationPage") - }, { - name: "Users", - divider: true, - href: "userprofiles.html", - selected: page.hasClass("userProfilesConfigurationPage") || (pageElem.id == "mediaLibraryPage" && getParameterByName('userId')) }, { name: "Advanced", divider: true, @@ -1202,7 +1212,7 @@ var Dashboard = { $(ApiClient).on("websocketopen", Dashboard.onWebSocketOpened) .on("websocketmessage", Dashboard.onWebSocketMessageReceived); - ApiClient.currentUserId(Dashboard.getCurrentUserId()); + ApiClient.setCurrentUserId(Dashboard.getCurrentUserId(), Dashboard.getAccessToken()); })(); @@ -1300,22 +1310,6 @@ $(function () { }); }); -$.fn.openPopup = function () { - - this.one('popupbeforeposition', function () { - - //$("body").on("touchmove.popup", false); - //$('body').addClass('bodyWithPopupOpen'); - - }).one('popupafterclose', function () { - //$("body").off("touchmove.popup"); - - //$('body').removeClass('bodyWithPopupOpen'); - }); - - return this.popup('open'); -}; - Dashboard.jQueryMobileInit(); $(document).on('pagebeforeshow', ".page", function () { diff --git a/dashboard-ui/scripts/wizardfinishpage.js b/dashboard-ui/scripts/wizardfinishpage.js index 1398fafb77..559f33946d 100644 --- a/dashboard-ui/scripts/wizardfinishpage.js +++ b/dashboard-ui/scripts/wizardfinishpage.js @@ -5,25 +5,11 @@ ApiClient.getServerConfiguration().done(function (config) { config.IsStartupWizardCompleted = true; - + ApiClient.updateServerConfiguration(config).done(function () { - ApiClient.getUsers().done(function (users) { - - for (var i = 0, length = users.length; i < length; i++) { - - if (users[i].Configuration.IsAdministrator) { - Dashboard.setCurrentUser(users[i].Id); - break; - } - - } - - Dashboard.navigate('dashboard.html'); - }); + Dashboard.navigate('dashboard.html'); }); }); - } - }; \ No newline at end of file diff --git a/dashboard-ui/thirdparty/mediabrowser.apiclient.js b/dashboard-ui/thirdparty/mediabrowser.apiclient.js index 6bfb1ad4ed..59cc76dc32 100644 --- a/dashboard-ui/thirdparty/mediabrowser.apiclient.js +++ b/dashboard-ui/thirdparty/mediabrowser.apiclient.js @@ -12,7 +12,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi keys.push((navigator.cpuClass || "")); var randomId = ''; - + if (localStorage) { // Since the above is not guaranteed to be unique per device, add a little more @@ -29,7 +29,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi keys.push(randomId); return MediaBrowser.SHA1(keys.join('|')); } - + /** * Creates a new api client instance * @param {String} serverAddress @@ -46,6 +46,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi var deviceName = "Web Browser"; var deviceId = generateDeviceId(); var currentUserId; + var accessToken; var webSocket; /** @@ -59,13 +60,15 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi /** * Gets or sets the current user id. */ - self.currentUserId = function (val) { + self.getCurrentUserId = function () { - if (val !== undefined) { - currentUserId = val; - } else { - return currentUserId; - } + return currentUserId; + }; + + self.setCurrentUserId = function (userId, token) { + + currentUserId = userId; + accessToken = token; }; deviceName = (function () { @@ -144,10 +147,14 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi }; } + if (accessToken) { + request.headers['X-MediaBrowser-Token'] = accessToken; + } + return $.ajax(request); }; - self.getJSON = function(url) { + self.getJSON = function (url) { return self.ajax({ type: "GET", @@ -349,6 +356,26 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi }); }; + self.logout = function () { + + var done = function () { + self.setCurrentUserId(null, null); + }; + + if (accessToken) { + var url = self.getUrl("Sessions/Logout"); + + return self.ajax({ + type: "POST", + url: url + }).done(done); + } + + var deferred = $.Deferred(); + deferred.resolveWith(null, []); + return deferred.promise().done(done); + }; + function getRemoteImagePrefix(options) { var urlPrefix; @@ -1319,7 +1346,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi dataType: "json" }); }; - + self.getNamedConfiguration = function (name) { var url = self.getUrl("System/Configuration/" + name); @@ -2115,8 +2142,11 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi if (ratio) { - if (options.width) { + if (options.minScale) { + ratio = Math.max(options.minScale, ratio); + } + if (options.width) { options.width = Math.round(options.width * ratio); } if (options.height) { @@ -2129,7 +2159,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi options.maxHeight = Math.round(options.maxHeight * ratio); } } - + options.quality = options.quality || (options.type.toLowerCase() == 'backdrop' ? 80 : 90); } @@ -2263,6 +2293,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi // Don't put these on the query string delete options.type; delete options.index; + delete options.minScale; return self.getUrl(url, options); }; @@ -3476,7 +3507,7 @@ MediaBrowser.SHA1 = function (msg) { } else if (browser.webkit) { browser.safari = true; } - + browser.mobile = (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)); jQuery.browser = browser;