diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 53db14b42..e7b0bbecd 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -1,54 +1,21 @@ (function () { - function onAuthFailure(data, textStatus, xhr) { - - var url = (this.url || '').toLowerCase(); - - // Bounce to the login screen, but not if a password entry fails, obviously - if (url.indexOf('/password') == -1 && - url.indexOf('/authenticate') == -1 && - !$($.mobile.activePage).is('.standalonePage')) { - - Dashboard.logout(false); - } - } - $.ajaxSetup({ - crossDomain: true, - - statusCode: { - - 401: onAuthFailure - }, - - error: function (event) { - - Dashboard.hideLoadingMsg(); - - if (!Dashboard.suppressAjaxErrors) { - setTimeout(function () { - - var msg = event.getResponseHeader("X-Application-Error-Code") || Dashboard.defaultErrorMessage; - Dashboard.showError(msg); - - }, 500); - } - } + crossDomain: true }); + if ($.browser.msie) { + // This is unfortunately required due to IE's over-aggressive caching. + // https://github.com/MediaBrowser/MediaBrowser/issues/179 + $.ajaxSetup({ + cache: false + }); + } })(); -if ($.browser.msie) { - - // This is unfortuantely required due to IE's over-aggressive caching. - // https://github.com/MediaBrowser/MediaBrowser/issues/179 - $.ajaxSetup({ - cache: false - }); -} - +// TODO: Deprecated in 1.9 $.support.cors = true; $(document).one('click', WebNotifications.requestPermission); @@ -71,6 +38,50 @@ var Dashboard = { //$.mobile.collapsible.prototype.options.contentTheme = "a"; }, + onRequestFail: function (e, data) { + + if (data.status == 401) { + + var url = data.url.toLowerCase(); + + // Bounce to the login screen, but not if a password entry fails, obviously + if (url.indexOf('/password') == -1 && + url.indexOf('/authenticate') == -1 && + !$($.mobile.activePage).is('.standalonePage')) { + + if (data.errorCode == "ParentalControl") { + + //alert(Globalize.translate('MessageLoggedOutParentalControl')); + + + Dashboard.alert({ + message: Globalize.translate('MessageLoggedOutParentalControl'), + callback: function() { + Dashboard.logout(false); + } + }); + + } else { + Dashboard.logout(false); + } + } + return; + } + + Dashboard.hideLoadingMsg(); + + if (!Dashboard.suppressAjaxErrors) { + + setTimeout(function () { + + var msg = data.errorCode || Dashboard.defaultErrorMessage; + + Dashboard.showError(msg); + + }, 500); + } + }, + getCurrentUser: function () { if (!Dashboard.getUserPromise) { @@ -161,6 +172,7 @@ var Dashboard = { store.removeItem("userId"); store.removeItem("token"); + store.removeItem("serverAddress"); var loginPage = !Dashboard.isConnectMode() ? 'login.html' : @@ -1222,7 +1234,9 @@ var Dashboard = { function initializeApiClient(apiClient) { - $(apiClient).off('.dashboard').on("websocketmessage.dashboard", Dashboard.onWebSocketMessageReceived); + $(apiClient).off('.dashboard') + .on("websocketmessage.dashboard", Dashboard.onWebSocketMessageReceived) + .on('requestfail.dashboard', Dashboard.onRequestFail); // TODO: Improve with http://webpjs.appspot.com/ apiClient.supportsWebP($.browser.chrome); @@ -1255,7 +1269,7 @@ var Dashboard = { initializeApiClient(ApiClient); - ConnectionManager.addApiClient(ApiClient); + ConnectionManager.addApiClient(ApiClient, true); } } else { diff --git a/dashboard-ui/thirdparty/apiclient/connectionmanager.js b/dashboard-ui/thirdparty/apiclient/connectionmanager.js index 74eb6ab8f..00928b700 100644 --- a/dashboard-ui/thirdparty/apiclient/connectionmanager.js +++ b/dashboard-ui/thirdparty/apiclient/connectionmanager.js @@ -66,9 +66,6 @@ url: url + "/mediabrowser/system/info/public", dataType: "json", - error: function () { - }, - timeout: 5000 }); @@ -92,17 +89,26 @@ return apiClients[0]; }; - self.addApiClient = function (apiClient) { + self.addApiClient = function (apiClient, enableAutomaticNetworking) { apiClients.push(apiClient); apiClient.getPublicSystemInfo().done(function (systemInfo) { - var server = {}; + var server = credentialProvider.credentials().servers.filter(function (s) { + + return s.Id == systemInfo.Id; + + })[0] || {}; + updateServerInfo(server, systemInfo); apiClient.serverInfo(server); $(this).trigger('apiclientcreated', [apiClient]); + + if (enableAutomaticNetworking) { + self.connectToServer(server); + } }); }; @@ -220,10 +226,6 @@ dataType: "json", headers: { "X-Connect-UserToken": accessToken - }, - - error: function () { - } }); @@ -241,10 +243,6 @@ dataType: "json", headers: { "X-MediaBrowser-Token": server.ExchangeToken - }, - - error: function () { - } }).done(function (auth) { @@ -272,10 +270,6 @@ dataType: "json", headers: { "X-MediaBrowser-Token": server.AccessToken - }, - - error: function () { - } }).done(function (systemInfo) { @@ -291,10 +285,6 @@ dataType: "json", headers: { "X-MediaBrowser-Token": server.AccessToken - }, - - error: function () { - } }).done(function (user) { @@ -413,7 +403,7 @@ } } - return $.when(promises).done(function () { + var done = function () { var credentials = credentialProvider.credentials(); @@ -431,8 +421,9 @@ connectUser = null; $(self).trigger('signedout'); + }; - }); + return $.when(promises).done(done); }; self.connectUserId = function () { @@ -456,10 +447,6 @@ dataType: "json", headers: { "X-Connect-UserToken": self.connectToken() - }, - - error: function () { - } }).done(function (servers) { @@ -758,11 +745,7 @@ password: md5 }, dataType: "json", - contentType: 'application/x-www-form-urlencoded; charset=UTF-8', - - error: function () { - // Don't show normal dashboard errors - } + contentType: 'application/x-www-form-urlencoded; charset=UTF-8' }).done(function (result) { diff --git a/dashboard-ui/thirdparty/apiclient/mediabrowser.apiclient.js b/dashboard-ui/thirdparty/apiclient/mediabrowser.apiclient.js index 7144c3efc..8cf8e7550 100644 --- a/dashboard-ui/thirdparty/apiclient/mediabrowser.apiclient.js +++ b/dashboard-ui/thirdparty/apiclient/mediabrowser.apiclient.js @@ -94,6 +94,24 @@ return val.substring(val.indexOf('=') + 1).replace("'", '%27'); }; + function onRequestFail(e) { + + $(self).trigger('requestfail', [ + { + url: this.url, + status: e.status, + errorCode: e.getResponseHeader("X-Application-Error-Code") + }]); + } + + function onRetryRequestFail(request) { + + $(self).trigger('requestfail', [ + { + url: request.url + }]); + } + /** * Wraps around jQuery ajax methods to add additional info to the request. */ @@ -122,20 +140,33 @@ } } - if (!self.enableAutomaticNetwork) { - return $.ajax(request); + if (!self.enableAutomaticNetwork || !self.serverInfo() || self.connectionMode == null) { + return $.ajax(request).fail(onRequestFail); } var deferred = $.Deferred(); - self.ajaxWithFailover(request, deferred); + self.ajaxWithFailover(request, deferred, true); return deferred.promise(); }; - function tryReconnectInternal(deferred, connectionMode, currentRetryCount) { + function switchConnectionMode(connectionMode) { - if (connectionMode == null) { - connectionMode = self.connectionMode; + var newConnectionMode; + + if (connectionMode == MediaBrowser.ConnectionMode.Local && serverInfo.RemoteAddress) { + newConnectionMode = MediaBrowser.ConnectionMode.Remote; } + else if (connectionMode == MediaBrowser.ConnectionMode.Remote && serverInfo.LocalAddress) { + newConnectionMode = MediaBrowser.ConnectionMode.Local; + } + else { + newConnectionMode = connectionMode; + } + + return newConnectionMode; + } + + function tryReconnectInternal(deferred, connectionMode, currentRetryCount) { var url = connectionMode == MediaBrowser.ConnectionMode.Local ? self.serverInfo().LocalAddress : @@ -147,36 +178,24 @@ url: url + "/mediabrowser/system/info/public", dataType: "json", - error: function () { - }, - timeout: 3000 }).done(function () { self.connectionMode = connectionMode; + self.serverAddress(url); deferred.resolve(); }).fail(function () { - currentRetryCount = currentRetryCount || 0; - if (currentRetryCount <= 6) { - var newConnectionMode; + var newConnectionMode = switchConnectionMode(connectionMode); - if (connectionMode == MediaBrowser.ConnectionMode.Local && serverInfo.RemoteAddress) { - newConnectionMode = MediaBrowser.ConnectionMode.Remote; - } - else if (connectionMode == MediaBrowser.ConnectionMode.Remote && serverInfo.LocalAddress) { - newConnectionMode = MediaBrowser.ConnectionMode.Local; - } - else { - newConnectionMode = connectionMode; - } - - tryReconnectInternal(deferred, newConnectionMode, currentRetryCount + 1); + setTimeout(function () { + tryReconnectInternal(deferred, newConnectionMode, currentRetryCount + 1); + }, 500); } else { deferred.reject(); @@ -187,7 +206,9 @@ function tryReconnect() { var deferred = $.Deferred(); - tryReconnectInternal(deferred); + setTimeout(function () { + tryReconnectInternal(deferred, self.connectionMode, 0); + }, 500); return deferred.promise(); } @@ -204,12 +225,9 @@ self.ajaxWithFailover = function (request, deferred, enableReconnection, replaceUrl) { - // Stop global error handlers - request.error = function () { }; - if (replaceUrl) { - var baseUrl = connectionMode == MediaBrowser.ConnectionMode.Local ? + var baseUrl = self.connectionMode == MediaBrowser.ConnectionMode.Local ? self.serverInfo().LocalAddress : self.serverInfo().RemoteAddress; @@ -220,22 +238,23 @@ deferred.resolveWith(null, [response]); - }).fail(function () { + }).fail(function (e, textStatus) { - if (enableReconnection !== false) { + // http://api.jquery.com/jQuery.ajax/ + if (enableReconnection && textStatus == "timeout") { tryReconnect().done(function () { self.ajaxWithFailover(request, deferred, false, true); }).fail(function () { - // TODO: Make sure global ajax error handlers fire + onRetryRequestFail(request); deferred.reject(); }); } else { - // TODO: Make sure global ajax error handlers fire + onRetryRequestFail(request); deferred.reject(); } }); @@ -277,6 +296,12 @@ self.serverInfo(server); self.connectionMode = connectionMode; self.enableAutomaticNetwork = true; + + var url = connectionMode == MediaBrowser.ConnectionMode.Local ? + self.serverInfo().LocalAddress : + self.serverInfo().RemoteAddress; + + self.serverAddress(url); }; self.isWebSocketSupported = function () { diff --git a/dashboard-ui/thirdparty/apiclient/network.js b/dashboard-ui/thirdparty/apiclient/network.js new file mode 100644 index 000000000..04f0bf855 --- /dev/null +++ b/dashboard-ui/thirdparty/apiclient/network.js @@ -0,0 +1,21 @@ +(function (globalScope, navigator) { + + function networkStatus() { + + var self = this; + + self.isOnline = function () { + + var online = navigator.onLine; + + if (online == null) { + online = true; + } + + return online; + }; + } + + globalScope.NetworkStatus = new networkStatus(); + +})(window, window.navigator); \ No newline at end of file