diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 84241f602a..53db14b422 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -772,12 +772,7 @@ var Dashboard = { ensureWebSocket: function () { - if (!("WebSocket" in window)) { - // Not supported by the browser - return; - } - - if (ApiClient.isWebSocketOpenOrConnecting()) { + if (ApiClient.isWebSocketOpenOrConnecting() || !ApiClient.isWebSocketSupported()) { return; } diff --git a/dashboard-ui/thirdparty/apiclient/connectionmanager.js b/dashboard-ui/thirdparty/apiclient/connectionmanager.js index 77f9e1322c..74eb6ab8f1 100644 --- a/dashboard-ui/thirdparty/apiclient/connectionmanager.js +++ b/dashboard-ui/thirdparty/apiclient/connectionmanager.js @@ -1,22 +1,22 @@ -if (!window.MediaBrowser) { - window.MediaBrowser = {}; -} +(function (globalScope, $) { -MediaBrowser.ConnectionManager = function ($) { + if (!globalScope.MediaBrowser) { + globalScope.MediaBrowser = {}; + } - MediaBrowser.ConnectionState = { + globalScope.MediaBrowser.ConnectionState = { Unavilable: 0, ServerSelection: 1, ServerSignIn: 2, SignedIn: 3 }; - MediaBrowser.ConnectionMode = { + globalScope.MediaBrowser.ConnectionMode = { Local: 0, Remote: 1 }; - return function (credentialProvider, appName, applicationVersion, deviceName, deviceId, capabilities) { + globalScope.MediaBrowser.ConnectionManager = function (credentialProvider, appName, applicationVersion, deviceName, deviceId, capabilities) { var self = this; var apiClients = []; @@ -79,7 +79,7 @@ MediaBrowser.ConnectionManager = function ($) { return connectUser; }; - self.appVersion = function() { + self.appVersion = function () { return applicationVersion; }; @@ -178,7 +178,7 @@ MediaBrowser.ConnectionManager = function ($) { function ensureWebSocket(apiClient) { - if (!apiClient.isWebSocketOpenOrConnecting) { + if (!apiClient.isWebSocketOpenOrConnecting && apiClient.isWebSocketSupported()) { apiClient.openWebSocket(); } } @@ -322,7 +322,7 @@ MediaBrowser.ConnectionManager = function ($) { } function getImageUrl(localUser) { - + if (connectUser && connectUser.ImageUrl) { return { url: connectUser.ImageUrl @@ -349,7 +349,7 @@ MediaBrowser.ConnectionManager = function ($) { }; } - self.user = function() { + self.user = function () { var deferred = $.Deferred(); @@ -371,7 +371,7 @@ MediaBrowser.ConnectionManager = function ($) { } function onEnsureConnectUserDone() { - + var apiClient = self.currentApiClient(); if (apiClient && apiClient.getCurrentUserId()) { apiClient.getUser(apiClient.getCurrentUserId()).done(function (u) { @@ -793,4 +793,4 @@ MediaBrowser.ConnectionManager = function ($) { }; }; -}(jQuery); \ No newline at end of file +})(window, jQuery); \ No newline at end of file diff --git a/dashboard-ui/thirdparty/apiclient/credentials.js b/dashboard-ui/thirdparty/apiclient/credentials.js index c606be9df4..fd1689b9b2 100644 --- a/dashboard-ui/thirdparty/apiclient/credentials.js +++ b/dashboard-ui/thirdparty/apiclient/credentials.js @@ -1,10 +1,10 @@ -if (!window.MediaBrowser) { - window.MediaBrowser = {}; -} +(function (globalScope, store, JSON) { -MediaBrowser.CredentialProvider = function (store) { + if (!globalScope.MediaBrowser) { + globalScope.MediaBrowser = {}; + } - return function () { + globalScope.MediaBrowser.CredentialProvider = function () { var self = this; var credentials; @@ -26,7 +26,7 @@ MediaBrowser.CredentialProvider = function (store) { store.setItem('servercredentials', JSON.stringify(get())); } - self.clear = function() { + self.clear = function () { credentials = null; store.removeItem('servercredentials'); }; @@ -40,40 +40,33 @@ MediaBrowser.CredentialProvider = function (store) { return get(); }; - self.addOrUpdateServer = function(list, server) { + self.addOrUpdateServer = function (list, server) { - var existing = list.filter(function(s) { + var existing = list.filter(function (s) { return s.Id == server.Id; })[0]; - if (existing) - { + if (existing) { // Merge the data existing.DateLastAccessed = Math.max(existing.DateLastAccessed || 0, server.DateLastAccessed || 0, new Date().getTime()); - if (server.AccessToken) - { + if (server.AccessToken) { existing.AccessToken = server.AccessToken; existing.UserId = server.UserId; } - if (server.ExchangeToken) - { + if (server.ExchangeToken) { existing.ExchangeToken = server.ExchangeToken; } - if (server.RemoteAddress) - { + if (server.RemoteAddress) { existing.RemoteAddress = server.RemoteAddress; } - if (server.LocalAddress) - { + if (server.LocalAddress) { existing.LocalAddress = server.LocalAddress; } - if (server.Name) - { + if (server.Name) { existing.Name = server.Name; } - if (server.WakeOnLanInfos && server.WakeOnLanInfos.length) - { + if (server.WakeOnLanInfos && server.WakeOnLanInfos.length) { existing.WakeOnLanInfos = server.WakeOnLanInfos; } } @@ -83,4 +76,4 @@ MediaBrowser.CredentialProvider = function (store) { }; }; -}(window.store); \ No newline at end of file +})(window, store, window.JSON); \ No newline at end of file diff --git a/dashboard-ui/thirdparty/apiclient/device.js b/dashboard-ui/thirdparty/apiclient/device.js index 7886b2ce74..dd3685a38a 100644 --- a/dashboard-ui/thirdparty/apiclient/device.js +++ b/dashboard-ui/thirdparty/apiclient/device.js @@ -1,10 +1,10 @@ -if (!window.MediaBrowser) { - window.MediaBrowser = {}; -} +(function (globalScope, store) { -(function (store) { + if (!globalScope.MediaBrowser) { + globalScope.MediaBrowser = {}; + } - MediaBrowser.generateDeviceId = function () { + globalScope.MediaBrowser.generateDeviceId = function () { var keys = []; @@ -27,4 +27,4 @@ return sha1(keys.join('|')); }; -})(store); \ No newline at end of file +})(window, store); \ No newline at end of file diff --git a/dashboard-ui/thirdparty/apiclient/mediabrowser.apiclient.js b/dashboard-ui/thirdparty/apiclient/mediabrowser.apiclient.js index 7e5a01e4af..7144c3efc8 100644 --- a/dashboard-ui/thirdparty/apiclient/mediabrowser.apiclient.js +++ b/dashboard-ui/thirdparty/apiclient/mediabrowser.apiclient.js @@ -1,8 +1,8 @@ -if (!window.MediaBrowser) { - window.MediaBrowser = {}; -} +(function (globalScope, $, JSON, WebSocket, setTimeout, devicePixelRatio, FileReader) { -MediaBrowser.ApiClient = function ($, JSON, WebSocket, setTimeout, devicePixelRatio, FileReader) { + if (!globalScope.MediaBrowser) { + globalScope.MediaBrowser = {}; + } /** * Creates a new api client instance @@ -10,7 +10,7 @@ MediaBrowser.ApiClient = function ($, JSON, WebSocket, setTimeout, devicePixelRa * @param {String} clientName * @param {String} applicationVersion */ - return function (serverAddress, clientName, applicationVersion, deviceName, deviceId, capabilities) { + globalScope.MediaBrowser.ApiClient = function (serverAddress, clientName, applicationVersion, deviceName, deviceId, capabilities) { if (!serverAddress) { throw new Error("Must supply a serverAddress"); @@ -122,7 +122,123 @@ MediaBrowser.ApiClient = function ($, JSON, WebSocket, setTimeout, devicePixelRa } } - return $.ajax(request); + if (!self.enableAutomaticNetwork) { + return $.ajax(request); + } + + var deferred = $.Deferred(); + self.ajaxWithFailover(request, deferred); + return deferred.promise(); + }; + + function tryReconnectInternal(deferred, connectionMode, currentRetryCount) { + + if (connectionMode == null) { + connectionMode = self.connectionMode; + } + + var url = connectionMode == MediaBrowser.ConnectionMode.Local ? + self.serverInfo().LocalAddress : + self.serverInfo().RemoteAddress; + + $.ajax({ + + type: "GET", + url: url + "/mediabrowser/system/info/public", + dataType: "json", + + error: function () { + }, + + timeout: 3000 + + }).done(function () { + + self.connectionMode = connectionMode; + + deferred.resolve(); + + }).fail(function () { + + currentRetryCount = currentRetryCount || 0; + + if (currentRetryCount <= 6) { + + 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; + } + + tryReconnectInternal(deferred, newConnectionMode, currentRetryCount + 1); + + } else { + deferred.reject(); + } + }); + } + + function tryReconnect() { + + var deferred = $.Deferred(); + tryReconnectInternal(deferred); + return deferred.promise(); + } + + function replaceServerAddress(url, newBaseUrl) { + + var index = url.toLowerCase().indexOf("/mediabrowser"); + + if (index != -1) { + return newBaseUrl + url.substring(index); + } + + return url; + } + + self.ajaxWithFailover = function (request, deferred, enableReconnection, replaceUrl) { + + // Stop global error handlers + request.error = function () { }; + + if (replaceUrl) { + + var baseUrl = connectionMode == MediaBrowser.ConnectionMode.Local ? + self.serverInfo().LocalAddress : + self.serverInfo().RemoteAddress; + + request.url = replaceServerAddress(request.url, baseUrl); + } + + $.ajax(request).done(function (response) { + + deferred.resolveWith(null, [response]); + + }).fail(function () { + + if (enableReconnection !== false) { + tryReconnect().done(function () { + + self.ajaxWithFailover(request, deferred, false, true); + + }).fail(function () { + + // TODO: Make sure global ajax error handlers fire + deferred.reject(); + + }); + } else { + + // TODO: Make sure global ajax error handlers fire + deferred.reject(); + } + }); }; self.getJSON = function (url) { @@ -158,6 +274,13 @@ MediaBrowser.ApiClient = function ($, JSON, WebSocket, setTimeout, devicePixelRa self.enableAutomaticNetworking = function (server, connectionMode) { + self.serverInfo(server); + self.connectionMode = connectionMode; + self.enableAutomaticNetwork = true; + }; + + self.isWebSocketSupported = function () { + return WebSocket != null; }; self.openWebSocket = function () { @@ -3194,4 +3317,4 @@ MediaBrowser.ApiClient = function ($, JSON, WebSocket, setTimeout, devicePixelRa }; -}(jQuery, window.JSON, window.WebSocket, setTimeout, window.devicePixelRatio, window.FileReader); \ No newline at end of file +})(window, jQuery, window.JSON, window.WebSocket, window.setTimeout, window.devicePixelRatio, window.FileReader); \ No newline at end of file diff --git a/dashboard-ui/thirdparty/apiclient/store.js b/dashboard-ui/thirdparty/apiclient/store.js index 663959d706..bcb184c4a5 100644 --- a/dashboard-ui/thirdparty/apiclient/store.js +++ b/dashboard-ui/thirdparty/apiclient/store.js @@ -1,4 +1,4 @@ -(function (window) { +(function (globalScope, localStorage, sessionStorage) { function myStore(defaultObject) { @@ -44,7 +44,7 @@ }; } - window.store = new myStore(window.localStorage); - window.sessionStore = new myStore(window.sessionStorage); + globalScope.store = new myStore(localStorage); + globalScope.sessionStore = new myStore(sessionStorage); -})(window); \ No newline at end of file +})(window, window.localStorage, window.sessionStorage); \ No newline at end of file