From 4dd9477bcdcd0eb6e00303a8e4230ea52faff0aa Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 23 Mar 2013 00:04:36 -0400 Subject: [PATCH] copy dashboard to the output folder and load from the file system, instead of using embedded resources --- ApiClient.js | 233 +- Html/Readme.txt | 4 - {Html => dashboard-ui}/about.html | 0 {Html => dashboard-ui}/addPlugin.html | 0 {Html => dashboard-ui}/advanced.html | 0 {Html => dashboard-ui}/advancedMetadata.html | 0 {Html => dashboard-ui}/css/images/bg.png | Bin .../css/images/checkMarkGreen.png | Bin .../css/images/checkmarkblack.png | Bin .../css/images/clients/android.png | Bin .../css/images/clients/dlna.png | Bin .../css/images/clients/html5.png | Bin .../css/images/clients/ios.png | Bin .../css/images/clients/mb.png | Bin .../css/images/clients/win8.png | Bin .../css/images/clients/windowsphone.png | Bin .../css/images/clients/windowsrt.png | Bin .../css/images/cloudNetwork.png | Bin .../css/images/currentUserDefaultBlack.png | Bin .../css/images/currentUserDefaultWhite.png | Bin .../css/images/defaultCollectionImage.png | Bin .../css/images/donatepp.png | Bin {Html => dashboard-ui}/css/images/home.png | Bin .../css/images/iossplash.png | Bin .../css/images/itemDetails/audioDefault.png | Bin .../css/images/itemDetails/gameDefault.png | Bin .../css/images/itemDetails/videoDefault.png | Bin .../css/images/leftArrowBlack.png | Bin .../css/images/leftArrowWhite.png | Bin .../css/images/logindefault.png | Bin .../css/images/mblogoicon.png | Bin .../css/images/mblogotextblack.png | Bin .../css/images/mblogotextwhite.png | Bin .../css/images/media/nextTrack.png | Bin .../css/images/media/pause.png | Bin .../css/images/media/play.png | Bin .../css/images/media/playCircle.png | Bin .../css/images/media/previousTrack.png | Bin .../css/images/media/stop.png | Bin .../css/images/movieFolder.png | Bin .../css/images/notifications/cancelled.png | Bin .../css/images/notifications/done.png | Bin .../css/images/notifications/download.png | Bin .../css/images/notifications/error.png | Bin .../css/images/notifications/info.png | Bin .../css/images/premiumflag.png | Bin .../css/images/registerpp.png | Bin .../css/images/rightArrow.png | Bin {Html => dashboard-ui}/css/images/stars.png | Bin .../css/images/suppbadge.png | Bin .../css/images/supporterflag.png | Bin .../css/images/toolsBlack.png | Bin .../css/images/toolsWhite.png | Bin .../css/images/touchicon.png | Bin .../css/images/touchicon114.png | Bin .../css/images/touchicon72.png | Bin .../css/images/userFlyoutDefault.png | Bin {Html => dashboard-ui}/css/site.css | 0 {Html => dashboard-ui}/dashboard.html | 0 {Html => dashboard-ui}/editUser.html | 0 {Html => dashboard-ui}/favicon.ico | Bin {Html => dashboard-ui}/index.html | 0 {Html => dashboard-ui}/itemDetails.html | 0 {Html => dashboard-ui}/itemList.html | 0 {Html => dashboard-ui}/library.html | 0 {Html => dashboard-ui}/log.html | 0 {Html => dashboard-ui}/login.html | 0 {Html => dashboard-ui}/metadata.html | 0 {Html => dashboard-ui}/metadataImages.html | 0 {Html => dashboard-ui}/pluginCatalog.html | 0 {Html => dashboard-ui}/pluginUpdates.html | 0 {Html => dashboard-ui}/plugins.html | 0 {Html => dashboard-ui}/scheduledTask.html | 0 {Html => dashboard-ui}/scheduledTasks.html | 0 .../scripts/AddPluginPage.js | 0 .../scripts/AdvancedConfigurationPage.js | 0 .../AdvancedMetadataConfigurationPage.js | 0 .../scripts/DashboardPage.js | 12 +- .../scripts/DisplaySettingsPage.js | 0 .../scripts/EditUserPage.js | 0 {Html => dashboard-ui}/scripts/Extensions.js | 175 -- {Html => dashboard-ui}/scripts/IndexPage.js | 0 .../scripts/ItemDetailPage.js | 0 .../scripts/ItemListPage.js | 0 {Html => dashboard-ui}/scripts/LogPage.js | 12 +- {Html => dashboard-ui}/scripts/LoginPage.js | 0 .../scripts/MediaLibraryPage.js | 0 {Html => dashboard-ui}/scripts/MediaPlayer.js | 7 +- .../scripts/MetadataConfigurationPage.js | 0 .../scripts/MetadataImagesPage.js | 0 .../scripts/PluginCatalogPage.js | 0 .../scripts/PluginUpdatesPage.js | 0 {Html => dashboard-ui}/scripts/PluginsPage.js | 0 .../scripts/ScheduledTaskPage.js | 0 .../scripts/ScheduledTasksPage.js | 12 +- .../scripts/SupporterKeyPage.js | 0 .../scripts/SupporterPage.js | 0 .../scripts/UpdatePasswordPage.js | 0 .../scripts/UserImagePage.js | 0 .../scripts/UserProfilesPage.js | 0 .../scripts/WizardFinishPage.js | 0 .../scripts/WizardStartPage.js | 0 .../scripts/WizardUserPage.js | 0 {Html => dashboard-ui}/scripts/aboutPage.js | 0 {Html => dashboard-ui}/scripts/site.js | 2407 ++++++++--------- {Html => dashboard-ui}/support.html | 0 {Html => dashboard-ui}/supporter.html | 0 {Html => dashboard-ui}/supporterKey.html | 0 .../font-awesome/faicons-v2.png | Bin .../font-awesome/faicons.png | Bin .../font-awesome/font/fontawesome-webfont.eot | Bin .../font-awesome/font/fontawesome-webfont.ttf | Bin .../font/fontawesome-webfont.woff | Bin .../font-awesome/images/ajax-loader.png | Bin .../images/icons-18-black-pack.png | Bin .../images/icons-18-white-pack.png | Bin .../images/icons-36-black-pack.png | Bin .../images/icons-36-white-pack.png | Bin .../jqm-icon-pack-3.0/font-awesome/index.html | 0 .../font-awesome/jqm-icon-pack-3.0.0-fa.css | 0 .../font-awesome/jqm-icon-pack-3.0.0-fa.scss | 0 .../original/images/ajax-loader.gif | Bin .../original/images/ajax-loader.png | Bin .../original/images/icons-18-black-pack.png | Bin .../original/images/icons-18-white-pack.png | Bin .../original/images/icons-36-black-pack.png | Bin .../original/images/icons-36-white-pack.png | Bin .../jqm-icon-pack-3.0/original/index.html | 0 .../original/jqm-icon-pack-2.0-original.css | 0 {Html => dashboard-ui}/uiSettings.html | 0 {Html => dashboard-ui}/updatePassword.html | 0 {Html => dashboard-ui}/userImage.html | 0 {Html => dashboard-ui}/userProfiles.html | 0 {Html => dashboard-ui}/wizardFinish.html | 0 {Html => dashboard-ui}/wizardLibrary.html | 0 {Html => dashboard-ui}/wizardStart.html | 0 {Html => dashboard-ui}/wizardUser.html | 0 137 files changed, 1424 insertions(+), 1438 deletions(-) delete mode 100644 Html/Readme.txt rename {Html => dashboard-ui}/about.html (100%) rename {Html => dashboard-ui}/addPlugin.html (100%) rename {Html => dashboard-ui}/advanced.html (100%) rename {Html => dashboard-ui}/advancedMetadata.html (100%) rename {Html => dashboard-ui}/css/images/bg.png (100%) rename {Html => dashboard-ui}/css/images/checkMarkGreen.png (100%) rename {Html => dashboard-ui}/css/images/checkmarkblack.png (100%) rename {Html => dashboard-ui}/css/images/clients/android.png (100%) rename {Html => dashboard-ui}/css/images/clients/dlna.png (100%) rename {Html => dashboard-ui}/css/images/clients/html5.png (100%) rename {Html => dashboard-ui}/css/images/clients/ios.png (100%) rename {Html => dashboard-ui}/css/images/clients/mb.png (100%) rename {Html => dashboard-ui}/css/images/clients/win8.png (100%) rename {Html => dashboard-ui}/css/images/clients/windowsphone.png (100%) rename {Html => dashboard-ui}/css/images/clients/windowsrt.png (100%) rename {Html => dashboard-ui}/css/images/cloudNetwork.png (100%) rename {Html => dashboard-ui}/css/images/currentUserDefaultBlack.png (100%) rename {Html => dashboard-ui}/css/images/currentUserDefaultWhite.png (100%) rename {Html => dashboard-ui}/css/images/defaultCollectionImage.png (100%) rename {Html => dashboard-ui}/css/images/donatepp.png (100%) rename {Html => dashboard-ui}/css/images/home.png (100%) rename {Html => dashboard-ui}/css/images/iossplash.png (100%) rename {Html => dashboard-ui}/css/images/itemDetails/audioDefault.png (100%) rename {Html => dashboard-ui}/css/images/itemDetails/gameDefault.png (100%) rename {Html => dashboard-ui}/css/images/itemDetails/videoDefault.png (100%) rename {Html => dashboard-ui}/css/images/leftArrowBlack.png (100%) rename {Html => dashboard-ui}/css/images/leftArrowWhite.png (100%) rename {Html => dashboard-ui}/css/images/logindefault.png (100%) rename {Html => dashboard-ui}/css/images/mblogoicon.png (100%) rename {Html => dashboard-ui}/css/images/mblogotextblack.png (100%) rename {Html => dashboard-ui}/css/images/mblogotextwhite.png (100%) rename {Html => dashboard-ui}/css/images/media/nextTrack.png (100%) rename {Html => dashboard-ui}/css/images/media/pause.png (100%) rename {Html => dashboard-ui}/css/images/media/play.png (100%) rename {Html => dashboard-ui}/css/images/media/playCircle.png (100%) rename {Html => dashboard-ui}/css/images/media/previousTrack.png (100%) rename {Html => dashboard-ui}/css/images/media/stop.png (100%) rename {Html => dashboard-ui}/css/images/movieFolder.png (100%) rename {Html => dashboard-ui}/css/images/notifications/cancelled.png (100%) rename {Html => dashboard-ui}/css/images/notifications/done.png (100%) rename {Html => dashboard-ui}/css/images/notifications/download.png (100%) rename {Html => dashboard-ui}/css/images/notifications/error.png (100%) rename {Html => dashboard-ui}/css/images/notifications/info.png (100%) rename {Html => dashboard-ui}/css/images/premiumflag.png (100%) rename {Html => dashboard-ui}/css/images/registerpp.png (100%) rename {Html => dashboard-ui}/css/images/rightArrow.png (100%) rename {Html => dashboard-ui}/css/images/stars.png (100%) rename {Html => dashboard-ui}/css/images/suppbadge.png (100%) rename {Html => dashboard-ui}/css/images/supporterflag.png (100%) rename {Html => dashboard-ui}/css/images/toolsBlack.png (100%) rename {Html => dashboard-ui}/css/images/toolsWhite.png (100%) rename {Html => dashboard-ui}/css/images/touchicon.png (100%) rename {Html => dashboard-ui}/css/images/touchicon114.png (100%) rename {Html => dashboard-ui}/css/images/touchicon72.png (100%) rename {Html => dashboard-ui}/css/images/userFlyoutDefault.png (100%) rename {Html => dashboard-ui}/css/site.css (100%) rename {Html => dashboard-ui}/dashboard.html (100%) rename {Html => dashboard-ui}/editUser.html (100%) rename {Html => dashboard-ui}/favicon.ico (100%) rename {Html => dashboard-ui}/index.html (100%) rename {Html => dashboard-ui}/itemDetails.html (100%) rename {Html => dashboard-ui}/itemList.html (100%) rename {Html => dashboard-ui}/library.html (100%) rename {Html => dashboard-ui}/log.html (100%) rename {Html => dashboard-ui}/login.html (100%) rename {Html => dashboard-ui}/metadata.html (100%) rename {Html => dashboard-ui}/metadataImages.html (100%) rename {Html => dashboard-ui}/pluginCatalog.html (100%) rename {Html => dashboard-ui}/pluginUpdates.html (100%) rename {Html => dashboard-ui}/plugins.html (100%) rename {Html => dashboard-ui}/scheduledTask.html (100%) rename {Html => dashboard-ui}/scheduledTasks.html (100%) rename {Html => dashboard-ui}/scripts/AddPluginPage.js (100%) rename {Html => dashboard-ui}/scripts/AdvancedConfigurationPage.js (100%) rename {Html => dashboard-ui}/scripts/AdvancedMetadataConfigurationPage.js (100%) rename {Html => dashboard-ui}/scripts/DashboardPage.js (94%) rename {Html => dashboard-ui}/scripts/DisplaySettingsPage.js (100%) rename {Html => dashboard-ui}/scripts/EditUserPage.js (100%) rename {Html => dashboard-ui}/scripts/Extensions.js (73%) rename {Html => dashboard-ui}/scripts/IndexPage.js (100%) rename {Html => dashboard-ui}/scripts/ItemDetailPage.js (100%) rename {Html => dashboard-ui}/scripts/ItemListPage.js (100%) rename {Html => dashboard-ui}/scripts/LogPage.js (71%) rename {Html => dashboard-ui}/scripts/LoginPage.js (100%) rename {Html => dashboard-ui}/scripts/MediaLibraryPage.js (100%) rename {Html => dashboard-ui}/scripts/MediaPlayer.js (95%) rename {Html => dashboard-ui}/scripts/MetadataConfigurationPage.js (100%) rename {Html => dashboard-ui}/scripts/MetadataImagesPage.js (100%) rename {Html => dashboard-ui}/scripts/PluginCatalogPage.js (100%) rename {Html => dashboard-ui}/scripts/PluginUpdatesPage.js (100%) rename {Html => dashboard-ui}/scripts/PluginsPage.js (100%) rename {Html => dashboard-ui}/scripts/ScheduledTaskPage.js (100%) rename {Html => dashboard-ui}/scripts/ScheduledTasksPage.js (84%) rename {Html => dashboard-ui}/scripts/SupporterKeyPage.js (100%) rename {Html => dashboard-ui}/scripts/SupporterPage.js (100%) rename {Html => dashboard-ui}/scripts/UpdatePasswordPage.js (100%) rename {Html => dashboard-ui}/scripts/UserImagePage.js (100%) rename {Html => dashboard-ui}/scripts/UserProfilesPage.js (100%) rename {Html => dashboard-ui}/scripts/WizardFinishPage.js (100%) rename {Html => dashboard-ui}/scripts/WizardStartPage.js (100%) rename {Html => dashboard-ui}/scripts/WizardUserPage.js (100%) rename {Html => dashboard-ui}/scripts/aboutPage.js (100%) rename {Html => dashboard-ui}/scripts/site.js (91%) rename {Html => dashboard-ui}/support.html (100%) rename {Html => dashboard-ui}/supporter.html (100%) rename {Html => dashboard-ui}/supporterKey.html (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons-v2.png (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons.png (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.eot (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.ttf (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.woff (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/font-awesome/images/ajax-loader.png (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-black-pack.png (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-white-pack.png (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-black-pack.png (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-white-pack.png (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/font-awesome/index.html (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.css (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.scss (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.gif (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.png (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-black-pack.png (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-white-pack.png (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-black-pack.png (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-white-pack.png (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/original/index.html (100%) rename {Html => dashboard-ui}/thirdparty/jqm-icon-pack-3.0/original/jqm-icon-pack-2.0-original.css (100%) rename {Html => dashboard-ui}/uiSettings.html (100%) rename {Html => dashboard-ui}/updatePassword.html (100%) rename {Html => dashboard-ui}/userImage.html (100%) rename {Html => dashboard-ui}/userProfiles.html (100%) rename {Html => dashboard-ui}/wizardFinish.html (100%) rename {Html => dashboard-ui}/wizardLibrary.html (100%) rename {Html => dashboard-ui}/wizardStart.html (100%) rename {Html => dashboard-ui}/wizardUser.html (100%) diff --git a/ApiClient.js b/ApiClient.js index f3b24cd29c..1d2d180065 100644 --- a/ApiClient.js +++ b/ApiClient.js @@ -2,7 +2,7 @@ window.MediaBrowser = {}; } -MediaBrowser.ApiClient = function ($, navigator) { +MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { /** * Creates a new api client instance @@ -15,8 +15,9 @@ MediaBrowser.ApiClient = function ($, navigator) { var self = this; var deviceName = "Web Browser"; - var deviceId = SHA1(navigator.userAgent + (navigator.cpuClass || "")); + var deviceId = MediaBrowser.SHA1(navigator.userAgent + (navigator.cpuClass || "")); var currentUserId; + var webSocket; /** * Gets the server host name. @@ -88,6 +89,55 @@ MediaBrowser.ApiClient = function ($, navigator) { return url; }; + self.openWebSocket = function (port) { + + var url = "ws://" + serverHostName + ":" + port + "/mediabrowser"; + + webSocket = new WebSocket(url); + + webSocket.onmessage = function (msg) { + msg = JSON.parse(msg.data); + $(self).trigger("websocketmessage", [msg]); + }; + + webSocket.onopen = function () { + setTimeout(function () { + $(self).trigger("websocketopen"); + }, 500); + }; + webSocket.onerror = function () { + setTimeout(function () { + $(self).trigger("websocketerror"); + }, 0); + }; + webSocket.onclose = function () { + setTimeout(function () { + $(self).trigger("websocketclose"); + }, 0); + }; + }; + + self.sendWebSocketMessage = function (name, data) { + + var msg = { MessageType: name }; + + if (data) { + msg.Data = data; + } + + msg = JSON.stringify(msg); + + webSocket.send(msg); + }; + + self.isWebSocketOpen = function () { + return webSocket && webSocket.readyState === WebSocket.OPEN; + }; + + self.isWebSocketOpenOrConnecting = function () { + return webSocket && (webSocket.readyState === WebSocket.OPEN || webSocket.readyState === WebSocket.CONNECTING); + }; + /** * Gets an item from the server * Omit itemId to get the root folder. @@ -1184,7 +1234,7 @@ MediaBrowser.ApiClient = function ($, navigator) { var url = self.getUrl("Users/" + userId + "/authenticate"); var postData = { - password: SHA1(password || "") + password: MediaBrowser.SHA1(password || "") }; return self.ajax({ @@ -1214,7 +1264,7 @@ MediaBrowser.ApiClient = function ($, navigator) { }; - postData.currentPassword = SHA1(currentPassword); + postData.currentPassword = MediaBrowser.SHA1(currentPassword); if (newPassword) { postData.newPassword = newPassword; @@ -1523,7 +1573,7 @@ MediaBrowser.ApiClient = function ($, navigator) { }; }; -}(jQuery, navigator); +}(jQuery, navigator, JSON, window.WebSocket, setTimeout); /** * Provides a friendly way to create an api client instance using information from the browser's current url @@ -1533,4 +1583,177 @@ MediaBrowser.ApiClient.create = function (clientName) { var loc = window.location; return new MediaBrowser.ApiClient(loc.protocol, loc.hostname, loc.port, clientName); +}; + +/** +* +* Secure Hash Algorithm (SHA1) +* http://www.webtoolkit.info/ +* +**/ +MediaBrowser.SHA1 = function (msg) { + + function rotate_left(n, s) { + var t4 = (n << s) | (n >>> (32 - s)); + return t4; + }; + + function lsb_hex(val) { + var str = ""; + var i; + var vh; + var vl; + + for (i = 0; i <= 6; i += 2) { + vh = (val >>> (i * 4 + 4)) & 0x0f; + vl = (val >>> (i * 4)) & 0x0f; + str += vh.toString(16) + vl.toString(16); + } + return str; + }; + + function cvt_hex(val) { + var str = ""; + var i; + var v; + + for (i = 7; i >= 0; i--) { + v = (val >>> (i * 4)) & 0x0f; + str += v.toString(16); + } + return str; + }; + + + function Utf8Encode(string) { + string = string.replace(/\r\n/g, "\n"); + var utftext = ""; + + for (var n = 0; n < string.length; n++) { + + var c = string.charCodeAt(n); + + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if ((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + + } + + return utftext; + }; + + var blockstart; + var i, j; + var W = new Array(80); + var H0 = 0x67452301; + var H1 = 0xEFCDAB89; + var H2 = 0x98BADCFE; + var H3 = 0x10325476; + var H4 = 0xC3D2E1F0; + var A, B, C, D, E; + var temp; + + msg = Utf8Encode(msg); + + var msg_len = msg.length; + + var word_array = new Array(); + for (i = 0; i < msg_len - 3; i += 4) { + j = msg.charCodeAt(i) << 24 | msg.charCodeAt(i + 1) << 16 | + msg.charCodeAt(i + 2) << 8 | msg.charCodeAt(i + 3); + word_array.push(j); + } + + switch (msg_len % 4) { + case 0: + i = 0x080000000; + break; + case 1: + i = msg.charCodeAt(msg_len - 1) << 24 | 0x0800000; + break; + + case 2: + i = msg.charCodeAt(msg_len - 2) << 24 | msg.charCodeAt(msg_len - 1) << 16 | 0x08000; + break; + + case 3: + i = msg.charCodeAt(msg_len - 3) << 24 | msg.charCodeAt(msg_len - 2) << 16 | msg.charCodeAt(msg_len - 1) << 8 | 0x80; + break; + } + + word_array.push(i); + + while ((word_array.length % 16) != 14) word_array.push(0); + + word_array.push(msg_len >>> 29); + word_array.push((msg_len << 3) & 0x0ffffffff); + + + for (blockstart = 0; blockstart < word_array.length; blockstart += 16) { + + for (i = 0; i < 16; i++) W[i] = word_array[blockstart + i]; + for (i = 16; i <= 79; i++) W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); + + A = H0; + B = H1; + C = H2; + D = H3; + E = H4; + + for (i = 0; i <= 19; i++) { + temp = (rotate_left(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5A827999) & 0x0ffffffff; + E = D; + D = C; + C = rotate_left(B, 30); + B = A; + A = temp; + } + + for (i = 20; i <= 39; i++) { + temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff; + E = D; + D = C; + C = rotate_left(B, 30); + B = A; + A = temp; + } + + for (i = 40; i <= 59; i++) { + temp = (rotate_left(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff; + E = D; + D = C; + C = rotate_left(B, 30); + B = A; + A = temp; + } + + for (i = 60; i <= 79; i++) { + temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff; + E = D; + D = C; + C = rotate_left(B, 30); + B = A; + A = temp; + } + + H0 = (H0 + A) & 0x0ffffffff; + H1 = (H1 + B) & 0x0ffffffff; + H2 = (H2 + C) & 0x0ffffffff; + H3 = (H3 + D) & 0x0ffffffff; + H4 = (H4 + E) & 0x0ffffffff; + + } + + var temp = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4); + + return temp.toLowerCase(); }; \ No newline at end of file diff --git a/Html/Readme.txt b/Html/Readme.txt deleted file mode 100644 index c47c075416..0000000000 --- a/Html/Readme.txt +++ /dev/null @@ -1,4 +0,0 @@ -All static files such as html, images, etc, need to be marked as embedded resources. - -Here is a link for more information regarding the Build Action property. -http://msdn.microsoft.com/en-us/library/0c6xyb66.aspx \ No newline at end of file diff --git a/Html/about.html b/dashboard-ui/about.html similarity index 100% rename from Html/about.html rename to dashboard-ui/about.html diff --git a/Html/addPlugin.html b/dashboard-ui/addPlugin.html similarity index 100% rename from Html/addPlugin.html rename to dashboard-ui/addPlugin.html diff --git a/Html/advanced.html b/dashboard-ui/advanced.html similarity index 100% rename from Html/advanced.html rename to dashboard-ui/advanced.html diff --git a/Html/advancedMetadata.html b/dashboard-ui/advancedMetadata.html similarity index 100% rename from Html/advancedMetadata.html rename to dashboard-ui/advancedMetadata.html diff --git a/Html/css/images/bg.png b/dashboard-ui/css/images/bg.png similarity index 100% rename from Html/css/images/bg.png rename to dashboard-ui/css/images/bg.png diff --git a/Html/css/images/checkMarkGreen.png b/dashboard-ui/css/images/checkMarkGreen.png similarity index 100% rename from Html/css/images/checkMarkGreen.png rename to dashboard-ui/css/images/checkMarkGreen.png diff --git a/Html/css/images/checkmarkblack.png b/dashboard-ui/css/images/checkmarkblack.png similarity index 100% rename from Html/css/images/checkmarkblack.png rename to dashboard-ui/css/images/checkmarkblack.png diff --git a/Html/css/images/clients/android.png b/dashboard-ui/css/images/clients/android.png similarity index 100% rename from Html/css/images/clients/android.png rename to dashboard-ui/css/images/clients/android.png diff --git a/Html/css/images/clients/dlna.png b/dashboard-ui/css/images/clients/dlna.png similarity index 100% rename from Html/css/images/clients/dlna.png rename to dashboard-ui/css/images/clients/dlna.png diff --git a/Html/css/images/clients/html5.png b/dashboard-ui/css/images/clients/html5.png similarity index 100% rename from Html/css/images/clients/html5.png rename to dashboard-ui/css/images/clients/html5.png diff --git a/Html/css/images/clients/ios.png b/dashboard-ui/css/images/clients/ios.png similarity index 100% rename from Html/css/images/clients/ios.png rename to dashboard-ui/css/images/clients/ios.png diff --git a/Html/css/images/clients/mb.png b/dashboard-ui/css/images/clients/mb.png similarity index 100% rename from Html/css/images/clients/mb.png rename to dashboard-ui/css/images/clients/mb.png diff --git a/Html/css/images/clients/win8.png b/dashboard-ui/css/images/clients/win8.png similarity index 100% rename from Html/css/images/clients/win8.png rename to dashboard-ui/css/images/clients/win8.png diff --git a/Html/css/images/clients/windowsphone.png b/dashboard-ui/css/images/clients/windowsphone.png similarity index 100% rename from Html/css/images/clients/windowsphone.png rename to dashboard-ui/css/images/clients/windowsphone.png diff --git a/Html/css/images/clients/windowsrt.png b/dashboard-ui/css/images/clients/windowsrt.png similarity index 100% rename from Html/css/images/clients/windowsrt.png rename to dashboard-ui/css/images/clients/windowsrt.png diff --git a/Html/css/images/cloudNetwork.png b/dashboard-ui/css/images/cloudNetwork.png similarity index 100% rename from Html/css/images/cloudNetwork.png rename to dashboard-ui/css/images/cloudNetwork.png diff --git a/Html/css/images/currentUserDefaultBlack.png b/dashboard-ui/css/images/currentUserDefaultBlack.png similarity index 100% rename from Html/css/images/currentUserDefaultBlack.png rename to dashboard-ui/css/images/currentUserDefaultBlack.png diff --git a/Html/css/images/currentUserDefaultWhite.png b/dashboard-ui/css/images/currentUserDefaultWhite.png similarity index 100% rename from Html/css/images/currentUserDefaultWhite.png rename to dashboard-ui/css/images/currentUserDefaultWhite.png diff --git a/Html/css/images/defaultCollectionImage.png b/dashboard-ui/css/images/defaultCollectionImage.png similarity index 100% rename from Html/css/images/defaultCollectionImage.png rename to dashboard-ui/css/images/defaultCollectionImage.png diff --git a/Html/css/images/donatepp.png b/dashboard-ui/css/images/donatepp.png similarity index 100% rename from Html/css/images/donatepp.png rename to dashboard-ui/css/images/donatepp.png diff --git a/Html/css/images/home.png b/dashboard-ui/css/images/home.png similarity index 100% rename from Html/css/images/home.png rename to dashboard-ui/css/images/home.png diff --git a/Html/css/images/iossplash.png b/dashboard-ui/css/images/iossplash.png similarity index 100% rename from Html/css/images/iossplash.png rename to dashboard-ui/css/images/iossplash.png diff --git a/Html/css/images/itemDetails/audioDefault.png b/dashboard-ui/css/images/itemDetails/audioDefault.png similarity index 100% rename from Html/css/images/itemDetails/audioDefault.png rename to dashboard-ui/css/images/itemDetails/audioDefault.png diff --git a/Html/css/images/itemDetails/gameDefault.png b/dashboard-ui/css/images/itemDetails/gameDefault.png similarity index 100% rename from Html/css/images/itemDetails/gameDefault.png rename to dashboard-ui/css/images/itemDetails/gameDefault.png diff --git a/Html/css/images/itemDetails/videoDefault.png b/dashboard-ui/css/images/itemDetails/videoDefault.png similarity index 100% rename from Html/css/images/itemDetails/videoDefault.png rename to dashboard-ui/css/images/itemDetails/videoDefault.png diff --git a/Html/css/images/leftArrowBlack.png b/dashboard-ui/css/images/leftArrowBlack.png similarity index 100% rename from Html/css/images/leftArrowBlack.png rename to dashboard-ui/css/images/leftArrowBlack.png diff --git a/Html/css/images/leftArrowWhite.png b/dashboard-ui/css/images/leftArrowWhite.png similarity index 100% rename from Html/css/images/leftArrowWhite.png rename to dashboard-ui/css/images/leftArrowWhite.png diff --git a/Html/css/images/logindefault.png b/dashboard-ui/css/images/logindefault.png similarity index 100% rename from Html/css/images/logindefault.png rename to dashboard-ui/css/images/logindefault.png diff --git a/Html/css/images/mblogoicon.png b/dashboard-ui/css/images/mblogoicon.png similarity index 100% rename from Html/css/images/mblogoicon.png rename to dashboard-ui/css/images/mblogoicon.png diff --git a/Html/css/images/mblogotextblack.png b/dashboard-ui/css/images/mblogotextblack.png similarity index 100% rename from Html/css/images/mblogotextblack.png rename to dashboard-ui/css/images/mblogotextblack.png diff --git a/Html/css/images/mblogotextwhite.png b/dashboard-ui/css/images/mblogotextwhite.png similarity index 100% rename from Html/css/images/mblogotextwhite.png rename to dashboard-ui/css/images/mblogotextwhite.png diff --git a/Html/css/images/media/nextTrack.png b/dashboard-ui/css/images/media/nextTrack.png similarity index 100% rename from Html/css/images/media/nextTrack.png rename to dashboard-ui/css/images/media/nextTrack.png diff --git a/Html/css/images/media/pause.png b/dashboard-ui/css/images/media/pause.png similarity index 100% rename from Html/css/images/media/pause.png rename to dashboard-ui/css/images/media/pause.png diff --git a/Html/css/images/media/play.png b/dashboard-ui/css/images/media/play.png similarity index 100% rename from Html/css/images/media/play.png rename to dashboard-ui/css/images/media/play.png diff --git a/Html/css/images/media/playCircle.png b/dashboard-ui/css/images/media/playCircle.png similarity index 100% rename from Html/css/images/media/playCircle.png rename to dashboard-ui/css/images/media/playCircle.png diff --git a/Html/css/images/media/previousTrack.png b/dashboard-ui/css/images/media/previousTrack.png similarity index 100% rename from Html/css/images/media/previousTrack.png rename to dashboard-ui/css/images/media/previousTrack.png diff --git a/Html/css/images/media/stop.png b/dashboard-ui/css/images/media/stop.png similarity index 100% rename from Html/css/images/media/stop.png rename to dashboard-ui/css/images/media/stop.png diff --git a/Html/css/images/movieFolder.png b/dashboard-ui/css/images/movieFolder.png similarity index 100% rename from Html/css/images/movieFolder.png rename to dashboard-ui/css/images/movieFolder.png diff --git a/Html/css/images/notifications/cancelled.png b/dashboard-ui/css/images/notifications/cancelled.png similarity index 100% rename from Html/css/images/notifications/cancelled.png rename to dashboard-ui/css/images/notifications/cancelled.png diff --git a/Html/css/images/notifications/done.png b/dashboard-ui/css/images/notifications/done.png similarity index 100% rename from Html/css/images/notifications/done.png rename to dashboard-ui/css/images/notifications/done.png diff --git a/Html/css/images/notifications/download.png b/dashboard-ui/css/images/notifications/download.png similarity index 100% rename from Html/css/images/notifications/download.png rename to dashboard-ui/css/images/notifications/download.png diff --git a/Html/css/images/notifications/error.png b/dashboard-ui/css/images/notifications/error.png similarity index 100% rename from Html/css/images/notifications/error.png rename to dashboard-ui/css/images/notifications/error.png diff --git a/Html/css/images/notifications/info.png b/dashboard-ui/css/images/notifications/info.png similarity index 100% rename from Html/css/images/notifications/info.png rename to dashboard-ui/css/images/notifications/info.png diff --git a/Html/css/images/premiumflag.png b/dashboard-ui/css/images/premiumflag.png similarity index 100% rename from Html/css/images/premiumflag.png rename to dashboard-ui/css/images/premiumflag.png diff --git a/Html/css/images/registerpp.png b/dashboard-ui/css/images/registerpp.png similarity index 100% rename from Html/css/images/registerpp.png rename to dashboard-ui/css/images/registerpp.png diff --git a/Html/css/images/rightArrow.png b/dashboard-ui/css/images/rightArrow.png similarity index 100% rename from Html/css/images/rightArrow.png rename to dashboard-ui/css/images/rightArrow.png diff --git a/Html/css/images/stars.png b/dashboard-ui/css/images/stars.png similarity index 100% rename from Html/css/images/stars.png rename to dashboard-ui/css/images/stars.png diff --git a/Html/css/images/suppbadge.png b/dashboard-ui/css/images/suppbadge.png similarity index 100% rename from Html/css/images/suppbadge.png rename to dashboard-ui/css/images/suppbadge.png diff --git a/Html/css/images/supporterflag.png b/dashboard-ui/css/images/supporterflag.png similarity index 100% rename from Html/css/images/supporterflag.png rename to dashboard-ui/css/images/supporterflag.png diff --git a/Html/css/images/toolsBlack.png b/dashboard-ui/css/images/toolsBlack.png similarity index 100% rename from Html/css/images/toolsBlack.png rename to dashboard-ui/css/images/toolsBlack.png diff --git a/Html/css/images/toolsWhite.png b/dashboard-ui/css/images/toolsWhite.png similarity index 100% rename from Html/css/images/toolsWhite.png rename to dashboard-ui/css/images/toolsWhite.png diff --git a/Html/css/images/touchicon.png b/dashboard-ui/css/images/touchicon.png similarity index 100% rename from Html/css/images/touchicon.png rename to dashboard-ui/css/images/touchicon.png diff --git a/Html/css/images/touchicon114.png b/dashboard-ui/css/images/touchicon114.png similarity index 100% rename from Html/css/images/touchicon114.png rename to dashboard-ui/css/images/touchicon114.png diff --git a/Html/css/images/touchicon72.png b/dashboard-ui/css/images/touchicon72.png similarity index 100% rename from Html/css/images/touchicon72.png rename to dashboard-ui/css/images/touchicon72.png diff --git a/Html/css/images/userFlyoutDefault.png b/dashboard-ui/css/images/userFlyoutDefault.png similarity index 100% rename from Html/css/images/userFlyoutDefault.png rename to dashboard-ui/css/images/userFlyoutDefault.png diff --git a/Html/css/site.css b/dashboard-ui/css/site.css similarity index 100% rename from Html/css/site.css rename to dashboard-ui/css/site.css diff --git a/Html/dashboard.html b/dashboard-ui/dashboard.html similarity index 100% rename from Html/dashboard.html rename to dashboard-ui/dashboard.html diff --git a/Html/editUser.html b/dashboard-ui/editUser.html similarity index 100% rename from Html/editUser.html rename to dashboard-ui/editUser.html diff --git a/Html/favicon.ico b/dashboard-ui/favicon.ico similarity index 100% rename from Html/favicon.ico rename to dashboard-ui/favicon.ico diff --git a/Html/index.html b/dashboard-ui/index.html similarity index 100% rename from Html/index.html rename to dashboard-ui/index.html diff --git a/Html/itemDetails.html b/dashboard-ui/itemDetails.html similarity index 100% rename from Html/itemDetails.html rename to dashboard-ui/itemDetails.html diff --git a/Html/itemList.html b/dashboard-ui/itemList.html similarity index 100% rename from Html/itemList.html rename to dashboard-ui/itemList.html diff --git a/Html/library.html b/dashboard-ui/library.html similarity index 100% rename from Html/library.html rename to dashboard-ui/library.html diff --git a/Html/log.html b/dashboard-ui/log.html similarity index 100% rename from Html/log.html rename to dashboard-ui/log.html diff --git a/Html/login.html b/dashboard-ui/login.html similarity index 100% rename from Html/login.html rename to dashboard-ui/login.html diff --git a/Html/metadata.html b/dashboard-ui/metadata.html similarity index 100% rename from Html/metadata.html rename to dashboard-ui/metadata.html diff --git a/Html/metadataImages.html b/dashboard-ui/metadataImages.html similarity index 100% rename from Html/metadataImages.html rename to dashboard-ui/metadataImages.html diff --git a/Html/pluginCatalog.html b/dashboard-ui/pluginCatalog.html similarity index 100% rename from Html/pluginCatalog.html rename to dashboard-ui/pluginCatalog.html diff --git a/Html/pluginUpdates.html b/dashboard-ui/pluginUpdates.html similarity index 100% rename from Html/pluginUpdates.html rename to dashboard-ui/pluginUpdates.html diff --git a/Html/plugins.html b/dashboard-ui/plugins.html similarity index 100% rename from Html/plugins.html rename to dashboard-ui/plugins.html diff --git a/Html/scheduledTask.html b/dashboard-ui/scheduledTask.html similarity index 100% rename from Html/scheduledTask.html rename to dashboard-ui/scheduledTask.html diff --git a/Html/scheduledTasks.html b/dashboard-ui/scheduledTasks.html similarity index 100% rename from Html/scheduledTasks.html rename to dashboard-ui/scheduledTasks.html diff --git a/Html/scripts/AddPluginPage.js b/dashboard-ui/scripts/AddPluginPage.js similarity index 100% rename from Html/scripts/AddPluginPage.js rename to dashboard-ui/scripts/AddPluginPage.js diff --git a/Html/scripts/AdvancedConfigurationPage.js b/dashboard-ui/scripts/AdvancedConfigurationPage.js similarity index 100% rename from Html/scripts/AdvancedConfigurationPage.js rename to dashboard-ui/scripts/AdvancedConfigurationPage.js diff --git a/Html/scripts/AdvancedMetadataConfigurationPage.js b/dashboard-ui/scripts/AdvancedMetadataConfigurationPage.js similarity index 100% rename from Html/scripts/AdvancedMetadataConfigurationPage.js rename to dashboard-ui/scripts/AdvancedMetadataConfigurationPage.js diff --git a/Html/scripts/DashboardPage.js b/dashboard-ui/scripts/DashboardPage.js similarity index 94% rename from Html/scripts/DashboardPage.js rename to dashboard-ui/scripts/DashboardPage.js index 47ff3b0c12..1e095281fa 100644 --- a/Html/scripts/DashboardPage.js +++ b/dashboard-ui/scripts/DashboardPage.js @@ -5,7 +5,7 @@ Dashboard.showLoadingMsg(); DashboardPage.pollForInfo(); DashboardPage.startInterval(); - $(document).on("websocketmessage", DashboardPage.onWebSocketMessage).on("websocketopen", DashboardPage.onWebSocketConnectionChange).on("websocketerror", DashboardPage.onWebSocketConnectionChange).on("websocketclose", DashboardPage.onWebSocketConnectionChange); + $(ApiClient).on("websocketmessage", DashboardPage.onWebSocketMessage).on("websocketopen", DashboardPage.onWebSocketConnectionChange).on("websocketerror", DashboardPage.onWebSocketConnectionChange).on("websocketclose", DashboardPage.onWebSocketConnectionChange); DashboardPage.lastAppUpdateCheck = null; DashboardPage.lastPluginUpdateCheck = null; @@ -13,21 +13,21 @@ onPageHide: function () { - $(document).off("websocketmessage", DashboardPage.onWebSocketMessage).off("websocketopen", DashboardPage.onWebSocketConnectionChange).off("websocketerror", DashboardPage.onWebSocketConnectionChange).off("websocketclose", DashboardPage.onWebSocketConnectionChange); + $(ApiClient).off("websocketmessage", DashboardPage.onWebSocketMessage).off("websocketopen", DashboardPage.onWebSocketConnectionChange).off("websocketerror", DashboardPage.onWebSocketConnectionChange).off("websocketclose", DashboardPage.onWebSocketConnectionChange); DashboardPage.stopInterval(); }, startInterval: function () { - if (Dashboard.isWebSocketOpen()) { - Dashboard.sendWebSocketMessage("DashboardInfoStart", "0,1500"); + if (ApiClient.isWebSocketOpen()) { + ApiClient.sendWebSocketMessage("DashboardInfoStart", "0,1500"); } }, stopInterval: function () { - if (Dashboard.isWebSocketOpen()) { - Dashboard.sendWebSocketMessage("DashboardInfoStop"); + if (ApiClient.isWebSocketOpen()) { + ApiClient.sendWebSocketMessage("DashboardInfoStop"); } }, diff --git a/Html/scripts/DisplaySettingsPage.js b/dashboard-ui/scripts/DisplaySettingsPage.js similarity index 100% rename from Html/scripts/DisplaySettingsPage.js rename to dashboard-ui/scripts/DisplaySettingsPage.js diff --git a/Html/scripts/EditUserPage.js b/dashboard-ui/scripts/EditUserPage.js similarity index 100% rename from Html/scripts/EditUserPage.js rename to dashboard-ui/scripts/EditUserPage.js diff --git a/Html/scripts/Extensions.js b/dashboard-ui/scripts/Extensions.js similarity index 73% rename from Html/scripts/Extensions.js rename to dashboard-ui/scripts/Extensions.js index 699ad61433..3621e341bf 100644 --- a/Html/scripts/Extensions.js +++ b/dashboard-ui/scripts/Extensions.js @@ -230,181 +230,6 @@ function parseISO8601Date(s, toLocal) { return new Date(ms); }; -/** -* -* Secure Hash Algorithm (SHA1) -* http://www.webtoolkit.info/ -* -**/ - -function SHA1(msg) { - - function rotate_left(n, s) { - var t4 = (n << s) | (n >>> (32 - s)); - return t4; - }; - - function lsb_hex(val) { - var str = ""; - var i; - var vh; - var vl; - - for (i = 0; i <= 6; i += 2) { - vh = (val >>> (i * 4 + 4)) & 0x0f; - vl = (val >>> (i * 4)) & 0x0f; - str += vh.toString(16) + vl.toString(16); - } - return str; - }; - - function cvt_hex(val) { - var str = ""; - var i; - var v; - - for (i = 7; i >= 0; i--) { - v = (val >>> (i * 4)) & 0x0f; - str += v.toString(16); - } - return str; - }; - - - function Utf8Encode(string) { - string = string.replace(/\r\n/g, "\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - - var c = string.charCodeAt(n); - - if (c < 128) { - utftext += String.fromCharCode(c); - } - else if ((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } - else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }; - - var blockstart; - var i, j; - var W = new Array(80); - var H0 = 0x67452301; - var H1 = 0xEFCDAB89; - var H2 = 0x98BADCFE; - var H3 = 0x10325476; - var H4 = 0xC3D2E1F0; - var A, B, C, D, E; - var temp; - - msg = Utf8Encode(msg); - - var msg_len = msg.length; - - var word_array = new Array(); - for (i = 0; i < msg_len - 3; i += 4) { - j = msg.charCodeAt(i) << 24 | msg.charCodeAt(i + 1) << 16 | - msg.charCodeAt(i + 2) << 8 | msg.charCodeAt(i + 3); - word_array.push(j); - } - - switch (msg_len % 4) { - case 0: - i = 0x080000000; - break; - case 1: - i = msg.charCodeAt(msg_len - 1) << 24 | 0x0800000; - break; - - case 2: - i = msg.charCodeAt(msg_len - 2) << 24 | msg.charCodeAt(msg_len - 1) << 16 | 0x08000; - break; - - case 3: - i = msg.charCodeAt(msg_len - 3) << 24 | msg.charCodeAt(msg_len - 2) << 16 | msg.charCodeAt(msg_len - 1) << 8 | 0x80; - break; - } - - word_array.push(i); - - while ((word_array.length % 16) != 14) word_array.push(0); - - word_array.push(msg_len >>> 29); - word_array.push((msg_len << 3) & 0x0ffffffff); - - - for (blockstart = 0; blockstart < word_array.length; blockstart += 16) { - - for (i = 0; i < 16; i++) W[i] = word_array[blockstart + i]; - for (i = 16; i <= 79; i++) W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); - - A = H0; - B = H1; - C = H2; - D = H3; - E = H4; - - for (i = 0; i <= 19; i++) { - temp = (rotate_left(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5A827999) & 0x0ffffffff; - E = D; - D = C; - C = rotate_left(B, 30); - B = A; - A = temp; - } - - for (i = 20; i <= 39; i++) { - temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff; - E = D; - D = C; - C = rotate_left(B, 30); - B = A; - A = temp; - } - - for (i = 40; i <= 59; i++) { - temp = (rotate_left(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff; - E = D; - D = C; - C = rotate_left(B, 30); - B = A; - A = temp; - } - - for (i = 60; i <= 79; i++) { - temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff; - E = D; - D = C; - C = rotate_left(B, 30); - B = A; - A = temp; - } - - H0 = (H0 + A) & 0x0ffffffff; - H1 = (H1 + B) & 0x0ffffffff; - H2 = (H2 + C) & 0x0ffffffff; - H3 = (H3 + D) & 0x0ffffffff; - H4 = (H4 + E) & 0x0ffffffff; - - } - - var temp = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4); - - return temp.toLowerCase(); - -} - // jqm.page.params.js - version 0.1 // Copyright (c) 2011, Kin Blas // All rights reserved. diff --git a/Html/scripts/IndexPage.js b/dashboard-ui/scripts/IndexPage.js similarity index 100% rename from Html/scripts/IndexPage.js rename to dashboard-ui/scripts/IndexPage.js diff --git a/Html/scripts/ItemDetailPage.js b/dashboard-ui/scripts/ItemDetailPage.js similarity index 100% rename from Html/scripts/ItemDetailPage.js rename to dashboard-ui/scripts/ItemDetailPage.js diff --git a/Html/scripts/ItemListPage.js b/dashboard-ui/scripts/ItemListPage.js similarity index 100% rename from Html/scripts/ItemListPage.js rename to dashboard-ui/scripts/ItemListPage.js diff --git a/Html/scripts/LogPage.js b/dashboard-ui/scripts/LogPage.js similarity index 71% rename from Html/scripts/LogPage.js rename to dashboard-ui/scripts/LogPage.js index 133eb34fbb..bed60ac1f5 100644 --- a/Html/scripts/LogPage.js +++ b/dashboard-ui/scripts/LogPage.js @@ -6,7 +6,7 @@ $('#logContents', this).html(''); - $(document).on("websocketmessage", LogPage.onWebSocketMessage).on("websocketopen", LogPage.onWebSocketConnectionChange).on("websocketerror", LogPage.onWebSocketConnectionChange).on("websocketclose", LogPage.onWebSocketConnectionChange); + $(ApiClient).on("websocketmessage", LogPage.onWebSocketMessage).on("websocketopen", LogPage.onWebSocketConnectionChange).on("websocketerror", LogPage.onWebSocketConnectionChange).on("websocketclose", LogPage.onWebSocketConnectionChange); LogPage.startInterval(); @@ -22,22 +22,22 @@ onPageHide: function () { - $(document).off("websocketmessage", LogPage.onWebSocketMessage).off("websocketopen", LogPage.onWebSocketConnectionChange).off("websocketerror", LogPage.onWebSocketConnectionChange).off("websocketclose", LogPage.onWebSocketConnectionChange); + $(ApiClient).off("websocketmessage", LogPage.onWebSocketMessage).off("websocketopen", LogPage.onWebSocketConnectionChange).off("websocketerror", LogPage.onWebSocketConnectionChange).off("websocketclose", LogPage.onWebSocketConnectionChange); LogPage.stopInterval(); }, startInterval: function () { - if (Dashboard.isWebSocketOpen()) { - Dashboard.sendWebSocketMessage("LogFileStart", "0,2000"); + if (ApiClient.isWebSocketOpen()) { + ApiClient.sendWebSocketMessage("LogFileStart", "0,2000"); } }, stopInterval: function () { - if (Dashboard.isWebSocketOpen()) { - Dashboard.sendWebSocketMessage("LogFileStop"); + if (ApiClient.isWebSocketOpen()) { + ApiClient.sendWebSocketMessage("LogFileStop"); } }, diff --git a/Html/scripts/LoginPage.js b/dashboard-ui/scripts/LoginPage.js similarity index 100% rename from Html/scripts/LoginPage.js rename to dashboard-ui/scripts/LoginPage.js diff --git a/Html/scripts/MediaLibraryPage.js b/dashboard-ui/scripts/MediaLibraryPage.js similarity index 100% rename from Html/scripts/MediaLibraryPage.js rename to dashboard-ui/scripts/MediaLibraryPage.js diff --git a/Html/scripts/MediaPlayer.js b/dashboard-ui/scripts/MediaPlayer.js similarity index 95% rename from Html/scripts/MediaPlayer.js rename to dashboard-ui/scripts/MediaPlayer.js index 928fb06b68..8b3043ba5c 100644 --- a/Html/scripts/MediaPlayer.js +++ b/dashboard-ui/scripts/MediaPlayer.js @@ -1,10 +1,13 @@ var MediaPlayer = { + testableAudioElement: document.createElement('audio'), + testableVideoElement: document.createElement('video'), + canPlay: function (item) { if (item.MediaType === "Video") { - var media = document.createElement('video'); + var media = MediaPlayer.testableVideoElement; if (media.canPlayType) { @@ -16,7 +19,7 @@ if (item.MediaType === "Audio") { - var media = document.createElement('audio'); + var media = MediaPlayer.testableAudioElement; if (media.canPlayType) { return media.canPlayType('audio/mpeg').replace(/no/, '') || media.canPlayType('audio/aac').replace(/no/, ''); diff --git a/Html/scripts/MetadataConfigurationPage.js b/dashboard-ui/scripts/MetadataConfigurationPage.js similarity index 100% rename from Html/scripts/MetadataConfigurationPage.js rename to dashboard-ui/scripts/MetadataConfigurationPage.js diff --git a/Html/scripts/MetadataImagesPage.js b/dashboard-ui/scripts/MetadataImagesPage.js similarity index 100% rename from Html/scripts/MetadataImagesPage.js rename to dashboard-ui/scripts/MetadataImagesPage.js diff --git a/Html/scripts/PluginCatalogPage.js b/dashboard-ui/scripts/PluginCatalogPage.js similarity index 100% rename from Html/scripts/PluginCatalogPage.js rename to dashboard-ui/scripts/PluginCatalogPage.js diff --git a/Html/scripts/PluginUpdatesPage.js b/dashboard-ui/scripts/PluginUpdatesPage.js similarity index 100% rename from Html/scripts/PluginUpdatesPage.js rename to dashboard-ui/scripts/PluginUpdatesPage.js diff --git a/Html/scripts/PluginsPage.js b/dashboard-ui/scripts/PluginsPage.js similarity index 100% rename from Html/scripts/PluginsPage.js rename to dashboard-ui/scripts/PluginsPage.js diff --git a/Html/scripts/ScheduledTaskPage.js b/dashboard-ui/scripts/ScheduledTaskPage.js similarity index 100% rename from Html/scripts/ScheduledTaskPage.js rename to dashboard-ui/scripts/ScheduledTaskPage.js diff --git a/Html/scripts/ScheduledTasksPage.js b/dashboard-ui/scripts/ScheduledTasksPage.js similarity index 84% rename from Html/scripts/ScheduledTasksPage.js rename to dashboard-ui/scripts/ScheduledTasksPage.js index 1a0a26d63b..5ef9ed5002 100644 --- a/Html/scripts/ScheduledTasksPage.js +++ b/dashboard-ui/scripts/ScheduledTasksPage.js @@ -6,25 +6,25 @@ ScheduledTasksPage.reloadList(true); - $(document).on("websocketmessage", ScheduledTasksPage.onWebSocketMessage).on("websocketopen", ScheduledTasksPage.onWebSocketConnectionChange).on("websocketerror", ScheduledTasksPage.onWebSocketConnectionChange).on("websocketclose", ScheduledTasksPage.onWebSocketConnectionChange); + $(ApiClient).on("websocketmessage", ScheduledTasksPage.onWebSocketMessage).on("websocketopen", ScheduledTasksPage.onWebSocketConnectionChange).on("websocketerror", ScheduledTasksPage.onWebSocketConnectionChange).on("websocketclose", ScheduledTasksPage.onWebSocketConnectionChange); }, onPageHide: function () { - $(document).off("websocketmessage", ScheduledTasksPage.onWebSocketMessage).off("websocketopen", ScheduledTasksPage.onWebSocketConnectionChange).off("websocketerror", ScheduledTasksPage.onWebSocketConnectionChange).off("websocketclose", ScheduledTasksPage.onWebSocketConnectionChange); + $(ApiClient).off("websocketmessage", ScheduledTasksPage.onWebSocketMessage).off("websocketopen", ScheduledTasksPage.onWebSocketConnectionChange).off("websocketerror", ScheduledTasksPage.onWebSocketConnectionChange).off("websocketclose", ScheduledTasksPage.onWebSocketConnectionChange); ScheduledTasksPage.stopInterval(); }, startInterval: function () { - if (Dashboard.isWebSocketOpen()) { - Dashboard.sendWebSocketMessage("ScheduledTasksInfoStart", "1500,1500"); + if (ApiClient.isWebSocketOpen()) { + ApiClient.sendWebSocketMessage("ScheduledTasksInfoStart", "1500,1500"); } }, stopInterval: function () { - if (Dashboard.isWebSocketOpen()) { - Dashboard.sendWebSocketMessage("ScheduledTasksInfoStop"); + if (ApiClient.isWebSocketOpen()) { + ApiClient.sendWebSocketMessage("ScheduledTasksInfoStop"); } }, diff --git a/Html/scripts/SupporterKeyPage.js b/dashboard-ui/scripts/SupporterKeyPage.js similarity index 100% rename from Html/scripts/SupporterKeyPage.js rename to dashboard-ui/scripts/SupporterKeyPage.js diff --git a/Html/scripts/SupporterPage.js b/dashboard-ui/scripts/SupporterPage.js similarity index 100% rename from Html/scripts/SupporterPage.js rename to dashboard-ui/scripts/SupporterPage.js diff --git a/Html/scripts/UpdatePasswordPage.js b/dashboard-ui/scripts/UpdatePasswordPage.js similarity index 100% rename from Html/scripts/UpdatePasswordPage.js rename to dashboard-ui/scripts/UpdatePasswordPage.js diff --git a/Html/scripts/UserImagePage.js b/dashboard-ui/scripts/UserImagePage.js similarity index 100% rename from Html/scripts/UserImagePage.js rename to dashboard-ui/scripts/UserImagePage.js diff --git a/Html/scripts/UserProfilesPage.js b/dashboard-ui/scripts/UserProfilesPage.js similarity index 100% rename from Html/scripts/UserProfilesPage.js rename to dashboard-ui/scripts/UserProfilesPage.js diff --git a/Html/scripts/WizardFinishPage.js b/dashboard-ui/scripts/WizardFinishPage.js similarity index 100% rename from Html/scripts/WizardFinishPage.js rename to dashboard-ui/scripts/WizardFinishPage.js diff --git a/Html/scripts/WizardStartPage.js b/dashboard-ui/scripts/WizardStartPage.js similarity index 100% rename from Html/scripts/WizardStartPage.js rename to dashboard-ui/scripts/WizardStartPage.js diff --git a/Html/scripts/WizardUserPage.js b/dashboard-ui/scripts/WizardUserPage.js similarity index 100% rename from Html/scripts/WizardUserPage.js rename to dashboard-ui/scripts/WizardUserPage.js diff --git a/Html/scripts/aboutPage.js b/dashboard-ui/scripts/aboutPage.js similarity index 100% rename from Html/scripts/aboutPage.js rename to dashboard-ui/scripts/aboutPage.js diff --git a/Html/scripts/site.js b/dashboard-ui/scripts/site.js similarity index 91% rename from Html/scripts/site.js rename to dashboard-ui/scripts/site.js index 27dc97810d..82f0f21d3f 100644 --- a/Html/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -1,1235 +1,1174 @@ -$.ajaxSetup({ - crossDomain: true, - - error: function (event, jqxhr, settings, exception) { - Dashboard.hideLoadingMsg(); - - if (!Dashboard.suppressAjaxErrors) { - setTimeout(function () { - - - var msg = event.getResponseHeader("X-Application-Error-Code") || Dashboard.defaultErrorMessage; - - Dashboard.showError(msg); - }, 500); - } - } -}); - -$.support.cors = true; - -$(document).one('click', WebNotifications.requestPermission); - -var Dashboard = { - jQueryMobileInit: function () { - - //$.mobile.defaultPageTransition = 'slide'; - - // Page - //$.mobile.page.prototype.options.theme = "a"; - //$.mobile.page.prototype.options.headerTheme = "a"; - //$.mobile.page.prototype.options.contentTheme = "a"; - //$.mobile.page.prototype.options.footerTheme = "a"; - - //$.mobile.button.prototype.options.theme = "c"; - $.mobile.listview.prototype.options.dividerTheme = "b"; - - $.mobile.popup.prototype.options.theme = "c"; - //$.mobile.collapsible.prototype.options.contentTheme = "a"; - }, - - getCurrentUser: function () { - - if (!Dashboard.getUserPromise) { - Dashboard.getUserPromise = ApiClient.getUser(Dashboard.getCurrentUserId()).fail(Dashboard.logout); - } - - return Dashboard.getUserPromise; - }, - - validateCurrentUser: function () { - Dashboard.getUserPromise = null; - - if (Dashboard.getCurrentUserId()) { - Dashboard.getCurrentUser(); - } - - var header = $('.header', $.mobile.activePage); - - if (header.length) { - // Re-render the header - header.remove(); - Dashboard.ensureHeader($.mobile.activePage); - } - }, - - getCurrentUserId: function () { - - var userId = localStorage.getItem("userId"); - - if (!userId) { - var autoLoginUserId = getParameterByName('u'); - - if (autoLoginUserId) { - userId = autoLoginUserId; - localStorage.setItem("userId", userId); - } - } - - return userId; - }, - - setCurrentUser: function (userId) { - localStorage.setItem("userId", userId); - ApiClient.currentUserId(userId); - Dashboard.getUserPromise = null; - }, - - logout: function () { - localStorage.removeItem("userId"); - Dashboard.getUserPromise = null; - ApiClient.currentUserId(null); - window.location = "login.html"; - }, - - showError: function (message) { - - $.mobile.loading('show', { - theme: "e", - text: message, - textonly: true, - textVisible: true - }); - - setTimeout(function () { - $.mobile.loading('hide'); - }, 2000); - }, - - alert: function (message) { - - $.mobile.loading('show', { - theme: "e", - text: message, - textonly: true, - textVisible: true - }); - - setTimeout(function () { - $.mobile.loading('hide'); - }, 2000); - }, - - updateSystemInfo: function (info) { - - var isFirstLoad = !Dashboard.lastSystemInfo; - - Dashboard.lastSystemInfo = info; - Dashboard.ensureWebSocket(info); - - if (!Dashboard.initialServerVersion) { - Dashboard.initialServerVersion = info.Version; - } - - if (info.HasPendingRestart) { - - Dashboard.hideDashboardVersionWarning(); - Dashboard.showServerRestartWarning(); - - } else { - - Dashboard.hideServerRestartWarning(); - - if (Dashboard.initialServerVersion != info.Version) { - - Dashboard.showDashboardVersionWarning(); - } - } - - if (isFirstLoad) { - Dashboard.showFailedAssemblies(info.FailedPluginAssemblies); - } - - Dashboard.showInProgressInstallations(info.InProgressInstallations); - }, - - showFailedAssemblies: function (failedAssemblies) { - - for (var i = 0, length = failedAssemblies.length; i < length; i++) { - - var assembly = failedAssemblies[i]; - - var html = ''; - - var index = assembly.lastIndexOf('\\'); - - if (index != -1) { - assembly = assembly.substring(index + 1); - } - - html += ''; - html += assembly + " failed to load."; - html += ''; - - Dashboard.showFooterNotification({ html: html }); - - } - }, - - showInProgressInstallations: function (installations) { - - installations = installations || []; - - for (var i = 0, length = installations.length; i < length; i++) { - - var installation = installations[i]; - - var percent = installation.PercentComplete || 0; - - if (percent < 100) { - Dashboard.showPackageInstallNotification(installation, "progress"); - } - } - - if (installations.length) { - - Dashboard.ensureInstallRefreshInterval(); - } else { - Dashboard.stopInstallRefreshInterval(); - } - }, - - ensureInstallRefreshInterval: function () { - - if (!Dashboard.installRefreshInterval) { - - if (Dashboard.isWebSocketOpen()) { - Dashboard.sendWebSocketMessage("SystemInfoStart", "0,350"); - } - Dashboard.installRefreshInterval = 1; - } - }, - - stopInstallRefreshInterval: function () { - - if (Dashboard.installRefreshInterval) { - if (Dashboard.isWebSocketOpen()) { - Dashboard.sendWebSocketMessage("SystemInfoStop"); - } - Dashboard.installRefreshInterval = null; - } - }, - - cancelInstallation: function (id) { - - ApiClient.cancelPackageInstallation(id).always(Dashboard.refreshSystemInfoFromServer); - - }, - - showServerRestartWarning: function () { - - var html = 'Please restart Media Browser Server to finish updating.'; - html += ''; - - Dashboard.showFooterNotification({ id: "serverRestartWarning", html: html, forceShow: true, allowHide: false }); - }, - - hideServerRestartWarning: function () { - - $('#serverRestartWarning').remove(); - }, - - showDashboardVersionWarning: function () { - - var html = 'Please refresh this page to receive new updates from the server.'; - html += ''; - - Dashboard.showFooterNotification({ id: "dashboardVersionWarning", html: html, forceShow: true, allowHide: false }); - }, - - reloadPage: function () { - - window.location.href = window.location.href; - }, - - hideDashboardVersionWarning: function () { - - $('#dashboardVersionWarning').remove(); - }, - - showFooterNotification: function (options) { - - var removeOnHide = !options.id; - - options.id = options.id || "notification" + new Date().getTime() + parseInt(Math.random()); - - var parentElem = $('#footerNotifications'); - - var elem = $('#' + options.id, parentElem); - - if (!elem.length) { - elem = $('

').appendTo(parentElem); - } - - var onclick = removeOnHide ? "$(\"#" + options.id + "\").remove();" : "$(\"#" + options.id + "\").hide();"; - - if (options.allowHide !== false) { - options.html += ""; - } - - if (options.forceShow) { - elem.show(); - } - - elem.html(options.html).trigger('create'); - - if (options.timeout) { - - setTimeout(function () { - - if (removeOnHide) { - elem.remove(); - } else { - elem.hide(); - } - - }, options.timeout); - } - }, - - getConfigurationPageUrl: function (name) { - return "ConfigurationPage?name=" + encodeURIComponent(name); - }, - - navigate: function (url, preserveQueryString) { - - var queryString = window.location.search; - if (preserveQueryString && queryString) { - url += queryString; - } - $.mobile.changePage(url); - }, - - showLoadingMsg: function () { - $.mobile.showPageLoadingMsg(); - }, - - hideLoadingMsg: function () { - $.mobile.hidePageLoadingMsg(); - }, - - processPluginConfigurationUpdateResult: function () { - - Dashboard.hideLoadingMsg(); - - Dashboard.alert("Settings saved."); - }, - - defaultErrorMessage: "There was an error processing the request.", - - processServerConfigurationUpdateResult: function (result) { - - Dashboard.hideLoadingMsg(); - - Dashboard.alert("Settings saved."); - }, - - confirm: function (message, title, callback) { - - $('#confirmFlyout').popup("close").remove(); - - var html = '
'; - - html += '
'; - html += '

' + title + '

'; - html += '
'; - - html += '
'; - - html += '
'; - html += message; - html += '
'; - - html += '

'; - html += '

'; - html += '
'; - - html += '
'; - - $(document.body).append(html); - - $('#confirmFlyout').popup().trigger('create').popup("open").on("popupafterclose", function () { - - if (callback) { - callback(this.confirm == true); - } - - $(this).off("popupafterclose").remove(); - }); - }, - - refreshSystemInfoFromServer: function () { - ApiClient.getSystemInfo().done(function (info) { - - Dashboard.updateSystemInfo(info); - }); - }, - - restartServer: function () { - - Dashboard.suppressAjaxErrors = true; - Dashboard.showLoadingMsg(); - - ApiClient.performPendingRestart().done(function () { - - setTimeout(function () { - Dashboard.reloadPageWhenServerAvailable(); - }, 250); - - }).fail(function () { - Dashboard.suppressAjaxErrors = false; - }); - }, - - reloadPageWhenServerAvailable: function (retryCount) { - - ApiClient.getSystemInfo().done(function (info) { - - // If this is back to false, the restart completed - if (!info.HasPendingRestart) { - Dashboard.reloadPage(); - } else { - Dashboard.retryReload(retryCount); - } - - }).fail(function() { - Dashboard.retryReload(retryCount); - }); - }, - - retryReload: function (retryCount) { - setTimeout(function () { - - retryCount = retryCount || 0; - retryCount++; - - if (retryCount < 10) { - Dashboard.reloadPageWhenServerAvailable(retryCount); - } else { - Dashboard.suppressAjaxErrors = false; - } - }, 500); - }, - - getPosterViewHtml: function (options) { - - var html = ""; - - for (var i = 0, length = options.items.length; i < length; i++) { - var item = options.items[i]; - - var hasPrimaryImage = item.ImageTags && item.ImageTags.Primary; - - var href = item.IsFolder ? (item.Id ? "itemList.html?parentId=" + item.Id : "#") : "itemDetails.html?id=" + item.Id; - - var showText = options.showTitle || !hasPrimaryImage || (item.Type !== 'Movie' && item.Type !== 'Series' && item.Type !== 'Season' && item.Type !== 'Trailer'); - - var cssClass = showText ? "posterViewItem" : "posterViewItem posterViewItemWithNoText"; - - html += "
"; - - if (options.preferBackdrop && item.BackdropImageTags && item.BackdropImageTags.length) { - html += ""; - } else if (hasPrimaryImage) { - html += ""; - } - else if (item.BackdropImageTags && item.BackdropImageTags.length) { - html += ""; - } else { - html += ""; - } - - if (showText) { - html += "
"; - html += item.Name; - html += "
"; - } - - html += "
"; - } - - return html; - }, - - showUserFlyout: function () { - - Dashboard.getCurrentUser().done(function (user) { - - var html = '
'; - - html += 'Close'; - - html += '
'; - html += '

' + user.Name + '

'; - html += '
'; - - html += '
'; - - html += '

'; - - var imageUrl = user.PrimaryImageTag ? ApiClient.getUserImageUrl(user.Id, { - - height: 400, - tag: user.PrimaryImageTag, - type: "Primary" - - }) : "css/images/userFlyoutDefault.png"; - - html += ''; - html += '

'; - - html += '

'; - html += '

'; - html += '
'; - - html += '
'; - - $(document.body).append(html); - - $('#userFlyout').popup().trigger('create').popup("open").on("popupafterclose", function () { - - $(this).off("popupafterclose").remove(); - }); - }); - }, - - selectDirectory: function (options) { - - options = options || {}; - - options.header = options.header || "Select Media Path"; - - var html = ''; - - $($.mobile.activePage).append(html); - - var popup = $('#popupDirectoryPicker').popup().trigger('create').popup("open").on("popupafterclose", function () { - - $('form', this).off("submit"); - $(this).off("click").off("popupafterclose").remove(); - - }).on("click", ".lnkDirectory", function () { - - var path = this.getAttribute('data-path'); - - Dashboard.refreshDirectoryBrowser(path); - }); - - var txtCurrentPath = $('#txtDirectoryPickerPath', popup); - - if (options.path) { - txtCurrentPath.val(options.path); - } - - $('form', popup).on('submit', function () { - - if (options.callback) { - options.callback($('#txtDirectoryPickerPath', this).val()); - } - - return false; - }); - - Dashboard.refreshDirectoryBrowser(txtCurrentPath.val()); - }, - - refreshDirectoryBrowser: function (path) { - var page = $.mobile.activePage; - - Dashboard.showLoadingMsg(); - - var promise; - - if (path === "Network") { - promise = ApiClient.getNetworkDevices(); - } - else if (path) { - promise = ApiClient.getDirectoryContents(path, { includeDirectories: true }); - } else { - promise = ApiClient.getDrives(); - } - - promise.done(function (folders) { - - $('#txtDirectoryPickerPath', page).val(path || ""); - - var html = ''; - - if (path) { - - var parentPath = path; - - if (parentPath.endsWith('\\')) { - parentPath = parentPath.substring(0, parentPath.length - 1); - } - - var lastIndex = parentPath.lastIndexOf('\\'); - parentPath = lastIndex == -1 ? "" : parentPath.substring(0, lastIndex); - - if (parentPath.endsWith(':')) { - parentPath += "\\"; - } - - if (parentPath == '\\') { - parentPath = "Network"; - } - - html += '
  • ..
  • '; - } - - for (var i = 0, length = folders.length; i < length; i++) { - - var folder = folders[i]; - - html += '
  • ' + folder.Name + '
  • '; - } - - if (!path) { - html += '
  • Network
  • '; - } - - $('#ulDirectoryPickerList', page).html(html).listview('refresh'); - - Dashboard.hideLoadingMsg(); - - }).fail(function () { - - $('#txtDirectoryPickerPath', page).val(""); - $('#ulDirectoryPickerList', page).html('').listview('refresh'); - - Dashboard.hideLoadingMsg(); - }); - }, - - getPluginSecurityInfo: function () { - - if (!Dashboard.getPluginSecurityInfoPromise) { - - var deferred = $.Deferred(); - - // Don't let this blow up the dashboard when it fails - $.ajax({ - type: "GET", - url: ApiClient.getUrl("Plugins/SecurityInfo"), - dataType: 'json', - - error: function () { - // Don't show normal dashboard errors - } - - }).done(function (result) { - deferred.resolveWith(null, [[result]]); - }); - - Dashboard.getPluginSecurityInfoPromise = deferred; - } - - return Dashboard.getPluginSecurityInfoPromise; - }, - - resetPluginSecurityInfo: function () { - Dashboard.getPluginSecurityInfoPromise = null; - }, - - ensureHeader: function (page) { - - if (!$('.header', page).length) { - - var isLoggedIn = Dashboard.getCurrentUserId(); - - if (isLoggedIn) { - - Dashboard.getCurrentUser().done(function (user) { - Dashboard.renderHeader(page, user); - }); - - } else { - - Dashboard.renderHeader(page); - } - } - }, - - renderHeader: function (page, user) { - - var headerHtml = ''; - headerHtml += '
    '; - - var isLibraryPage = page.hasClass('libraryPage'); - - headerHtml += ''; - - var imageColor = isLibraryPage ? "White" : "Black"; - - if (user && !page.hasClass('wizardPage')) { - headerHtml += ''; - } - - headerHtml += '
    '; - page.prepend(headerHtml); - - Dashboard.getPluginSecurityInfo().done(function (pluginSecurityInfo) { - if (pluginSecurityInfo.IsMBSupporter) { - $('').insertBefore('.btnTools', page); - } - }); - }, - - ensureToolsMenu: function (page) { - - if (!page.hasClass('type-interior')) { - return; - } - - var sidebar = $('.toolsSidebar', page); - - if (!sidebar.length) { - - var html = '
    '; - - html += '

    Tools

    '; - - html += ''; - - // content-secondary - html += '
    '; - - $(page).append(html); - } - }, - - getToolsMenuLinks: function (page) { - - var pageElem = page[0]; - - return [{ - name: "Dashboard", - href: "dashboard.html", - selected: pageElem.id == "dashboardPage" - }, { - name: "Media Library", - href: "library.html", - selected: pageElem.id == "mediaLibraryPage" - }, { - name: "Metadata", - href: "metadata.html", - selected: pageElem.id == "metadataConfigurationPage" || pageElem.id == "advancedMetadataConfigurationPage" || pageElem.id == "metadataImagesConfigurationPage" - }, { - name: "Plugins", - href: "plugins.html", - selected: page.hasClass("pluginConfigurationPage") - }, { - name: "User Profiles", - href: "userProfiles.html", - selected: page.hasClass("userProfilesConfigurationPage") - }, { - name: "Display Settings", - href: "uiSettings.html", - selected: pageElem.id == "displaySettingsPage" - }, { - name: "Advanced", - href: "advanced.html", - selected: pageElem.id == "advancedConfigurationPage" - }, { - name: "Scheduled Tasks", - href: "scheduledTasks.html", - selected: pageElem.id == "scheduledTasksPage" || pageElem.id == "scheduledTaskPage" - }, { - name: "Help", - href: "support.html", - selected: pageElem.id == "supportPage" || pageElem.id == "logPage" || pageElem.id == "supporterPage" || pageElem.id == "supporterKeyPage" || pageElem.id == "aboutPage" - }]; - - }, - - ensureWebSocket: function (systemInfo) { - - if (!("WebSocket" in window)) { - // Not supported by the browser - return; - } - - if (Dashboard.webSocket) { - if (Dashboard.webSocket.readyState === WebSocket.OPEN || Dashboard.webSocket.readyState === WebSocket.CONNECTING) { - return; - } - } - - systemInfo = systemInfo || Dashboard.lastSystemInfo; - - var url = "ws://" + ApiClient.serverHostName() + ":" + systemInfo.WebSocketPortNumber + "/mediabrowser"; - - var ws = new WebSocket(url); - - ws.onmessage = Dashboard.onWebSocketMessage; - - ws.onopen = function () { - setTimeout(function () { - $(document).trigger("websocketopen"); - }, 500); - }; - ws.onerror = function () { - setTimeout(function () { - $(document).trigger("websocketerror"); - }, 0); - }; - ws.onclose = function () { - setTimeout(function () { - $(document).trigger("websocketclose"); - }, 0); - }; - - Dashboard.webSocket = ws; - }, - - resetWebSocketPingInterval: function () { - - if (Dashboard.pingWebSocketInterval) { - clearInterval(Dashboard.pingWebSocketInterval); - Dashboard.pingWebSocketInterval = null; - } - Dashboard.pingWebSocketInterval = setInterval(Dashboard.pingWebSocket, 30000); - }, - - pingWebSocket: function () { - - // Send a ping to the server every so often to try and keep the connection alive - if (Dashboard.isWebSocketOpen()) { - Dashboard.sendWebSocketMessage("ping"); - } - - }, - - onWebSocketMessage: function (msg) { - - msg = JSON.parse(msg.data); - - if (msg.MessageType === "LibraryChanged") { - Dashboard.processLibraryUpdateNotification(msg.Data); - } - else if (msg.MessageType === "UserDeleted") { - Dashboard.validateCurrentUser(); - } - else if (msg.MessageType === "SystemInfo") { - Dashboard.updateSystemInfo(msg.Data); - } - else if (msg.MessageType === "HasPendingRestartChanged") { - Dashboard.updateSystemInfo(msg.Data); - } - else if (msg.MessageType === "UserUpdated") { - Dashboard.validateCurrentUser(); - - var user = msg.Data; - - if (user.Id == Dashboard.getCurrentUserId()) { - - $('.currentUsername').html(user.Name); - } - } - else if (msg.MessageType === "PackageInstallationCompleted") { - Dashboard.showPackageInstallNotification(msg.Data, "completed"); - Dashboard.refreshSystemInfoFromServer(); - } - else if (msg.MessageType === "PackageInstallationFailed") { - Dashboard.showPackageInstallNotification(msg.Data, "failed"); - Dashboard.refreshSystemInfoFromServer(); - } - else if (msg.MessageType === "PackageInstallationCancelled") { - Dashboard.showPackageInstallNotification(msg.Data, "cancelled"); - Dashboard.refreshSystemInfoFromServer(); - } - else if (msg.MessageType === "PackageInstalling") { - Dashboard.showPackageInstallNotification(msg.Data, "progress"); - Dashboard.refreshSystemInfoFromServer(); - } - else if (msg.MessageType === "ScheduledTaskEndExecute") { - - Dashboard.showTaskCompletionNotification(msg.Data); - } - - $(document).trigger("websocketmessage", [msg]); - }, - - sendWebSocketMessage: function (name, data) { - - var msg = { MessageType: name }; - - if (data) { - msg.Data = data; - } - - msg = JSON.stringify(msg); - - Dashboard.webSocket.send(msg); - }, - - isWebSocketOpen: function () { - return Dashboard.webSocket && Dashboard.webSocket.readyState === WebSocket.OPEN; - }, - - showTaskCompletionNotification: function (result) { - - var html = ''; - - if (result.Status == "Completed") { - html += ''; - return; - } - else if (result.Status == "Cancelled") { - html += ''; - return; - } - else { - html += ''; - } - - html += ''; - html += result.Name + " " + result.Status; - html += ''; - - var timeout = 0; - - if (result.Status == 'Cancelled') { - timeout = 2000; - } - - Dashboard.showFooterNotification({ html: html, id: result.Id, forceShow: true, timeout: timeout }); - }, - - showPackageInstallNotification: function (installation, status) { - - var html = ''; - - if (status == 'completed') { - html += ''; - } - else if (status == 'cancelled') { - html += ''; - } - else if (status == 'failed') { - html += ''; - } - else if (status == 'progress') { - html += ''; - } - - html += ''; - - if (status == 'completed') { - html += installation.Name + ' ' + installation.Version + ' installation completed'; - } - else if (status == 'cancelled') { - html += installation.Name + ' ' + installation.Version + ' installation was cancelled'; - } - else if (status == 'failed') { - html += installation.Name + ' ' + installation.Version + ' installation failed'; - } - else if (status == 'progress') { - html += 'Installing ' + installation.Name + ' ' + installation.Version; - } - - html += ''; - - if (status == 'progress') { - - var percentComplete = Math.round(installation.PercentComplete || 0); - - html += ''; - html += '' + percentComplete + '%'; - html += ''; - - if (percentComplete < 100) { - var btnId = "btnCancel" + installation.Id; - html += ''; - } - } - - var timeout = 0; - - if (status == 'cancelled') { - timeout = 2000; - } - - var forceShow = status != "progress"; - var allowHide = status != "progress" && status != 'cancelled'; - - Dashboard.showFooterNotification({ html: html, id: installation.Id, timeout: timeout, forceShow: forceShow, allowHide: allowHide }); - }, - - processLibraryUpdateNotification: function (data) { - - var newItems = data.ItemsAdded.filter(function (a) { - return !a.IsFolder; - }); - - if (!Dashboard.newItems) { - Dashboard.newItems = []; - } - - for (var i = 0, length = newItems.length ; i < length; i++) { - - Dashboard.newItems.push(newItems[i]); - } - - if (Dashboard.newItemTimeout) { - clearTimeout(Dashboard.newItemTimeout); - } - - Dashboard.newItemTimeout = setTimeout(Dashboard.onNewItemTimerStopped, 60000); - }, - - onNewItemTimerStopped: function () { - - var newItems = Dashboard.newItems; - - newItems = newItems.sort(function (a, b) { - - if (a.PrimaryImageTag && b.PrimaryImageTag) { - return 0; - } - - if (a.PrimaryImageTag) { - return -1; - } - - return 1; - }); - - Dashboard.newItems = []; - Dashboard.newItemTimeout = null; - - // Show at most 3 notifications - for (var i = 0, length = Math.min(newItems.length, 3) ; i < length; i++) { - - var item = newItems[i]; - - var data = { - title: "New " + item.Type, - body: item.Name, - timeout: 6000 - }; - - if (item.PrimaryImageTag) { - data.icon = ApiClient.getImageUrl(item.Id, { - width: 100, - tag: item.PrimaryImageTag, - type: "Primary" - }); - - if (!item.Id || data.icon.indexOf("undefined") != -1) { - alert("bad image url: " + JSON.stringify(item)); - console.log("bad image url: " + JSON.stringify(item)); - - continue; - } - } - - WebNotifications.show(data); - } - }, - - ensurePageTitle: function (page) { - - if (!page.hasClass('type-interior')) { - return; - } - - var pageElem = page[0]; - - if (pageElem.hasPageTitle) { - return; - } - - var parent = $('.content-primary', page); - - if (!parent.length) { - parent = $('.ui-content', page)[0]; - } - - $(parent).prepend("

    " + (document.title || " ") + "

    "); - - pageElem.hasPageTitle = true; - }, - - setPageTitle: function (title) { - - $('.pageTitle', $.mobile.activePage).html(title); - - if (title) { - document.title = title; - } - }, - - metroColors: ["#6FBD45", "#4BB3DD", "#4164A5", "#E12026", "#800080", "#E1B222", "#008040", "#0094FF", "#FF00C7", "#FF870F", "#7F0037"], - - getRandomMetroColor: function () { - - var index = Math.floor(Math.random() * (Dashboard.metroColors.length - 1)); - - return Dashboard.metroColors[index]; - } - -}; - -var ApiClient = MediaBrowser.ApiClient.create("Dashboard"); - -$(function () { - - var footerHtml = ''; - - - $(document.body).append(footerHtml); -}); - -Dashboard.jQueryMobileInit(); - -$(document).on('pagebeforeshow', ".page", function () { - - Dashboard.refreshSystemInfoFromServer(); - - var page = $(this); - - Dashboard.ensureHeader(page); - Dashboard.ensurePageTitle(page); - -}).on('pageinit', ".page", function () { - - var page = $(this); - - var userId = Dashboard.getCurrentUserId(); - ApiClient.currentUserId(userId); - - if (!userId) { - - if (this.id !== "loginPage" && !page.hasClass('wizardPage')) { - - Dashboard.logout(); - } - } - - else { - - Dashboard.getCurrentUser().done(function (user) { - - if (user.Configuration.IsAdministrator) { - Dashboard.ensureToolsMenu(page); - } - }); - } +$.ajaxSetup({ + crossDomain: true, + + error: function (event, jqxhr, settings, exception) { + Dashboard.hideLoadingMsg(); + + if (!Dashboard.suppressAjaxErrors) { + setTimeout(function () { + + + var msg = event.getResponseHeader("X-Application-Error-Code") || Dashboard.defaultErrorMessage; + + Dashboard.showError(msg); + }, 500); + } + } +}); + +$.support.cors = true; + +$(document).one('click', WebNotifications.requestPermission); + +var Dashboard = { + jQueryMobileInit: function () { + + //$.mobile.defaultPageTransition = 'slide'; + + // Page + //$.mobile.page.prototype.options.theme = "a"; + //$.mobile.page.prototype.options.headerTheme = "a"; + //$.mobile.page.prototype.options.contentTheme = "a"; + //$.mobile.page.prototype.options.footerTheme = "a"; + + //$.mobile.button.prototype.options.theme = "c"; + $.mobile.listview.prototype.options.dividerTheme = "b"; + + $.mobile.popup.prototype.options.theme = "c"; + //$.mobile.collapsible.prototype.options.contentTheme = "a"; + }, + + getCurrentUser: function () { + + if (!Dashboard.getUserPromise) { + Dashboard.getUserPromise = ApiClient.getUser(Dashboard.getCurrentUserId()).fail(Dashboard.logout); + } + + return Dashboard.getUserPromise; + }, + + validateCurrentUser: function () { + Dashboard.getUserPromise = null; + + if (Dashboard.getCurrentUserId()) { + Dashboard.getCurrentUser(); + } + + var header = $('.header', $.mobile.activePage); + + if (header.length) { + // Re-render the header + header.remove(); + Dashboard.ensureHeader($.mobile.activePage); + } + }, + + getCurrentUserId: function () { + + var userId = localStorage.getItem("userId"); + + if (!userId) { + var autoLoginUserId = getParameterByName('u'); + + if (autoLoginUserId) { + userId = autoLoginUserId; + localStorage.setItem("userId", userId); + } + } + + return userId; + }, + + setCurrentUser: function (userId) { + localStorage.setItem("userId", userId); + ApiClient.currentUserId(userId); + Dashboard.getUserPromise = null; + }, + + logout: function () { + localStorage.removeItem("userId"); + Dashboard.getUserPromise = null; + ApiClient.currentUserId(null); + window.location = "login.html"; + }, + + showError: function (message) { + + $.mobile.loading('show', { + theme: "e", + text: message, + textonly: true, + textVisible: true + }); + + setTimeout(function () { + $.mobile.loading('hide'); + }, 2000); + }, + + alert: function (message) { + + $.mobile.loading('show', { + theme: "e", + text: message, + textonly: true, + textVisible: true + }); + + setTimeout(function () { + $.mobile.loading('hide'); + }, 2000); + }, + + updateSystemInfo: function (info) { + + var isFirstLoad = !Dashboard.lastSystemInfo; + + Dashboard.lastSystemInfo = info; + Dashboard.ensureWebSocket(info); + + if (!Dashboard.initialServerVersion) { + Dashboard.initialServerVersion = info.Version; + } + + if (info.HasPendingRestart) { + + Dashboard.hideDashboardVersionWarning(); + Dashboard.showServerRestartWarning(); + + } else { + + Dashboard.hideServerRestartWarning(); + + if (Dashboard.initialServerVersion != info.Version) { + + Dashboard.showDashboardVersionWarning(); + } + } + + if (isFirstLoad) { + Dashboard.showFailedAssemblies(info.FailedPluginAssemblies); + } + + Dashboard.showInProgressInstallations(info.InProgressInstallations); + }, + + showFailedAssemblies: function (failedAssemblies) { + + for (var i = 0, length = failedAssemblies.length; i < length; i++) { + + var assembly = failedAssemblies[i]; + + var html = ''; + + var index = assembly.lastIndexOf('\\'); + + if (index != -1) { + assembly = assembly.substring(index + 1); + } + + html += ''; + html += assembly + " failed to load."; + html += ''; + + Dashboard.showFooterNotification({ html: html }); + + } + }, + + showInProgressInstallations: function (installations) { + + installations = installations || []; + + for (var i = 0, length = installations.length; i < length; i++) { + + var installation = installations[i]; + + var percent = installation.PercentComplete || 0; + + if (percent < 100) { + Dashboard.showPackageInstallNotification(installation, "progress"); + } + } + + if (installations.length) { + + Dashboard.ensureInstallRefreshInterval(); + } else { + Dashboard.stopInstallRefreshInterval(); + } + }, + + ensureInstallRefreshInterval: function () { + + if (!Dashboard.installRefreshInterval) { + + if (ApiClient.isWebSocketOpen()) { + ApiClient.sendWebSocketMessage("SystemInfoStart", "0,350"); + } + Dashboard.installRefreshInterval = 1; + } + }, + + stopInstallRefreshInterval: function () { + + if (Dashboard.installRefreshInterval) { + if (ApiClient.isWebSocketOpen()) { + ApiClient.sendWebSocketMessage("SystemInfoStop"); + } + Dashboard.installRefreshInterval = null; + } + }, + + cancelInstallation: function (id) { + + ApiClient.cancelPackageInstallation(id).always(Dashboard.refreshSystemInfoFromServer); + + }, + + showServerRestartWarning: function () { + + var html = 'Please restart Media Browser Server to finish updating.'; + html += ''; + + Dashboard.showFooterNotification({ id: "serverRestartWarning", html: html, forceShow: true, allowHide: false }); + }, + + hideServerRestartWarning: function () { + + $('#serverRestartWarning').remove(); + }, + + showDashboardVersionWarning: function () { + + var html = 'Please refresh this page to receive new updates from the server.'; + html += ''; + + Dashboard.showFooterNotification({ id: "dashboardVersionWarning", html: html, forceShow: true, allowHide: false }); + }, + + reloadPage: function () { + + window.location.href = window.location.href; + }, + + hideDashboardVersionWarning: function () { + + $('#dashboardVersionWarning').remove(); + }, + + showFooterNotification: function (options) { + + var removeOnHide = !options.id; + + options.id = options.id || "notification" + new Date().getTime() + parseInt(Math.random()); + + var parentElem = $('#footerNotifications'); + + var elem = $('#' + options.id, parentElem); + + if (!elem.length) { + elem = $('

    ').appendTo(parentElem); + } + + var onclick = removeOnHide ? "$(\"#" + options.id + "\").remove();" : "$(\"#" + options.id + "\").hide();"; + + if (options.allowHide !== false) { + options.html += ""; + } + + if (options.forceShow) { + elem.show(); + } + + elem.html(options.html).trigger('create'); + + if (options.timeout) { + + setTimeout(function () { + + if (removeOnHide) { + elem.remove(); + } else { + elem.hide(); + } + + }, options.timeout); + } + }, + + getConfigurationPageUrl: function (name) { + return "ConfigurationPage?name=" + encodeURIComponent(name); + }, + + navigate: function (url, preserveQueryString) { + + var queryString = window.location.search; + if (preserveQueryString && queryString) { + url += queryString; + } + $.mobile.changePage(url); + }, + + showLoadingMsg: function () { + $.mobile.showPageLoadingMsg(); + }, + + hideLoadingMsg: function () { + $.mobile.hidePageLoadingMsg(); + }, + + processPluginConfigurationUpdateResult: function () { + + Dashboard.hideLoadingMsg(); + + Dashboard.alert("Settings saved."); + }, + + defaultErrorMessage: "There was an error processing the request.", + + processServerConfigurationUpdateResult: function (result) { + + Dashboard.hideLoadingMsg(); + + Dashboard.alert("Settings saved."); + }, + + confirm: function (message, title, callback) { + + $('#confirmFlyout').popup("close").remove(); + + var html = '
    '; + + html += '
    '; + html += '

    ' + title + '

    '; + html += '
    '; + + html += '
    '; + + html += '
    '; + html += message; + html += '
    '; + + html += '

    '; + html += '

    '; + html += '
    '; + + html += '
    '; + + $(document.body).append(html); + + $('#confirmFlyout').popup().trigger('create').popup("open").on("popupafterclose", function () { + + if (callback) { + callback(this.confirm == true); + } + + $(this).off("popupafterclose").remove(); + }); + }, + + refreshSystemInfoFromServer: function () { + ApiClient.getSystemInfo().done(function (info) { + + Dashboard.updateSystemInfo(info); + }); + }, + + restartServer: function () { + + Dashboard.suppressAjaxErrors = true; + Dashboard.showLoadingMsg(); + + ApiClient.performPendingRestart().done(function () { + + setTimeout(function () { + Dashboard.reloadPageWhenServerAvailable(); + }, 250); + + }).fail(function () { + Dashboard.suppressAjaxErrors = false; + }); + }, + + reloadPageWhenServerAvailable: function (retryCount) { + + ApiClient.getSystemInfo().done(function (info) { + + // If this is back to false, the restart completed + if (!info.HasPendingRestart) { + Dashboard.reloadPage(); + } else { + Dashboard.retryReload(retryCount); + } + + }).fail(function() { + Dashboard.retryReload(retryCount); + }); + }, + + retryReload: function (retryCount) { + setTimeout(function () { + + retryCount = retryCount || 0; + retryCount++; + + if (retryCount < 10) { + Dashboard.reloadPageWhenServerAvailable(retryCount); + } else { + Dashboard.suppressAjaxErrors = false; + } + }, 500); + }, + + getPosterViewHtml: function (options) { + + var html = ""; + + for (var i = 0, length = options.items.length; i < length; i++) { + var item = options.items[i]; + + var hasPrimaryImage = item.ImageTags && item.ImageTags.Primary; + + var href = item.IsFolder ? (item.Id ? "itemList.html?parentId=" + item.Id : "#") : "itemDetails.html?id=" + item.Id; + + var showText = options.showTitle || !hasPrimaryImage || (item.Type !== 'Movie' && item.Type !== 'Series' && item.Type !== 'Season' && item.Type !== 'Trailer'); + + var cssClass = showText ? "posterViewItem" : "posterViewItem posterViewItemWithNoText"; + + html += "
    "; + + if (options.preferBackdrop && item.BackdropImageTags && item.BackdropImageTags.length) { + html += ""; + } else if (hasPrimaryImage) { + html += ""; + } + else if (item.BackdropImageTags && item.BackdropImageTags.length) { + html += ""; + } else { + html += ""; + } + + if (showText) { + html += "
    "; + html += item.Name; + html += "
    "; + } + + html += "
    "; + } + + return html; + }, + + showUserFlyout: function () { + + Dashboard.getCurrentUser().done(function (user) { + + var html = '
    '; + + html += 'Close'; + + html += '
    '; + html += '

    ' + user.Name + '

    '; + html += '
    '; + + html += '
    '; + + html += '

    '; + + var imageUrl = user.PrimaryImageTag ? ApiClient.getUserImageUrl(user.Id, { + + height: 400, + tag: user.PrimaryImageTag, + type: "Primary" + + }) : "css/images/userFlyoutDefault.png"; + + html += ''; + html += '

    '; + + html += '

    '; + html += '

    '; + html += '
    '; + + html += '
    '; + + $(document.body).append(html); + + $('#userFlyout').popup().trigger('create').popup("open").on("popupafterclose", function () { + + $(this).off("popupafterclose").remove(); + }); + }); + }, + + selectDirectory: function (options) { + + options = options || {}; + + options.header = options.header || "Select Media Path"; + + var html = ''; + + $($.mobile.activePage).append(html); + + var popup = $('#popupDirectoryPicker').popup().trigger('create').popup("open").on("popupafterclose", function () { + + $('form', this).off("submit"); + $(this).off("click").off("popupafterclose").remove(); + + }).on("click", ".lnkDirectory", function () { + + var path = this.getAttribute('data-path'); + + Dashboard.refreshDirectoryBrowser(path); + }); + + var txtCurrentPath = $('#txtDirectoryPickerPath', popup); + + if (options.path) { + txtCurrentPath.val(options.path); + } + + $('form', popup).on('submit', function () { + + if (options.callback) { + options.callback($('#txtDirectoryPickerPath', this).val()); + } + + return false; + }); + + Dashboard.refreshDirectoryBrowser(txtCurrentPath.val()); + }, + + refreshDirectoryBrowser: function (path) { + var page = $.mobile.activePage; + + Dashboard.showLoadingMsg(); + + var promise; + + if (path === "Network") { + promise = ApiClient.getNetworkDevices(); + } + else if (path) { + promise = ApiClient.getDirectoryContents(path, { includeDirectories: true }); + } else { + promise = ApiClient.getDrives(); + } + + promise.done(function (folders) { + + $('#txtDirectoryPickerPath', page).val(path || ""); + + var html = ''; + + if (path) { + + var parentPath = path; + + if (parentPath.endsWith('\\')) { + parentPath = parentPath.substring(0, parentPath.length - 1); + } + + var lastIndex = parentPath.lastIndexOf('\\'); + parentPath = lastIndex == -1 ? "" : parentPath.substring(0, lastIndex); + + if (parentPath.endsWith(':')) { + parentPath += "\\"; + } + + if (parentPath == '\\') { + parentPath = "Network"; + } + + html += '
  • ..
  • '; + } + + for (var i = 0, length = folders.length; i < length; i++) { + + var folder = folders[i]; + + html += '
  • ' + folder.Name + '
  • '; + } + + if (!path) { + html += '
  • Network
  • '; + } + + $('#ulDirectoryPickerList', page).html(html).listview('refresh'); + + Dashboard.hideLoadingMsg(); + + }).fail(function () { + + $('#txtDirectoryPickerPath', page).val(""); + $('#ulDirectoryPickerList', page).html('').listview('refresh'); + + Dashboard.hideLoadingMsg(); + }); + }, + + getPluginSecurityInfo: function () { + + if (!Dashboard.getPluginSecurityInfoPromise) { + + var deferred = $.Deferred(); + + // Don't let this blow up the dashboard when it fails + $.ajax({ + type: "GET", + url: ApiClient.getUrl("Plugins/SecurityInfo"), + dataType: 'json', + + error: function () { + // Don't show normal dashboard errors + } + + }).done(function (result) { + deferred.resolveWith(null, [[result]]); + }); + + Dashboard.getPluginSecurityInfoPromise = deferred; + } + + return Dashboard.getPluginSecurityInfoPromise; + }, + + resetPluginSecurityInfo: function () { + Dashboard.getPluginSecurityInfoPromise = null; + }, + + ensureHeader: function (page) { + + if (!$('.header', page).length) { + + var isLoggedIn = Dashboard.getCurrentUserId(); + + if (isLoggedIn) { + + Dashboard.getCurrentUser().done(function (user) { + Dashboard.renderHeader(page, user); + }); + + } else { + + Dashboard.renderHeader(page); + } + } + }, + + renderHeader: function (page, user) { + + var headerHtml = ''; + headerHtml += '
    '; + + var isLibraryPage = page.hasClass('libraryPage'); + + headerHtml += ''; + + var imageColor = isLibraryPage ? "White" : "Black"; + + if (user && !page.hasClass('wizardPage')) { + headerHtml += ''; + } + + headerHtml += '
    '; + page.prepend(headerHtml); + + Dashboard.getPluginSecurityInfo().done(function (pluginSecurityInfo) { + if (pluginSecurityInfo.IsMBSupporter) { + $('').insertBefore('.btnTools', page); + } + }); + }, + + ensureToolsMenu: function (page) { + + if (!page.hasClass('type-interior')) { + return; + } + + var sidebar = $('.toolsSidebar', page); + + if (!sidebar.length) { + + var html = '
    '; + + html += '

    Tools

    '; + + html += ''; + + // content-secondary + html += '
    '; + + $(page).append(html); + } + }, + + getToolsMenuLinks: function (page) { + + var pageElem = page[0]; + + return [{ + name: "Dashboard", + href: "dashboard.html", + selected: pageElem.id == "dashboardPage" + }, { + name: "Media Library", + href: "library.html", + selected: pageElem.id == "mediaLibraryPage" + }, { + name: "Metadata", + href: "metadata.html", + selected: pageElem.id == "metadataConfigurationPage" || pageElem.id == "advancedMetadataConfigurationPage" || pageElem.id == "metadataImagesConfigurationPage" + }, { + name: "Plugins", + href: "plugins.html", + selected: page.hasClass("pluginConfigurationPage") + }, { + name: "User Profiles", + href: "userProfiles.html", + selected: page.hasClass("userProfilesConfigurationPage") + }, { + name: "Display Settings", + href: "uiSettings.html", + selected: pageElem.id == "displaySettingsPage" + }, { + name: "Advanced", + href: "advanced.html", + selected: pageElem.id == "advancedConfigurationPage" + }, { + name: "Scheduled Tasks", + href: "scheduledTasks.html", + selected: pageElem.id == "scheduledTasksPage" || pageElem.id == "scheduledTaskPage" + }, { + name: "Help", + href: "support.html", + selected: pageElem.id == "supportPage" || pageElem.id == "logPage" || pageElem.id == "supporterPage" || pageElem.id == "supporterKeyPage" || pageElem.id == "aboutPage" + }]; + + }, + + ensureWebSocket: function (systemInfo) { + + if (!("WebSocket" in window)) { + // Not supported by the browser + return; + } + + if (ApiClient.isWebSocketOpenOrConnecting()) { + return; + } + + systemInfo = systemInfo || Dashboard.lastSystemInfo; + + ApiClient.openWebSocket(systemInfo.WebSocketPortNumber); + + $(ApiClient).on("websocketmessage", Dashboard.onWebSocketMessageReceived); + }, + + onWebSocketMessageReceived: function (msg) { + + if (msg.MessageType === "LibraryChanged") { + Dashboard.processLibraryUpdateNotification(msg.Data); + } + else if (msg.MessageType === "UserDeleted") { + Dashboard.validateCurrentUser(); + } + else if (msg.MessageType === "SystemInfo") { + Dashboard.updateSystemInfo(msg.Data); + } + else if (msg.MessageType === "HasPendingRestartChanged") { + Dashboard.updateSystemInfo(msg.Data); + } + else if (msg.MessageType === "UserUpdated") { + Dashboard.validateCurrentUser(); + + var user = msg.Data; + + if (user.Id == Dashboard.getCurrentUserId()) { + + $('.currentUsername').html(user.Name); + } + } + else if (msg.MessageType === "PackageInstallationCompleted") { + Dashboard.showPackageInstallNotification(msg.Data, "completed"); + Dashboard.refreshSystemInfoFromServer(); + } + else if (msg.MessageType === "PackageInstallationFailed") { + Dashboard.showPackageInstallNotification(msg.Data, "failed"); + Dashboard.refreshSystemInfoFromServer(); + } + else if (msg.MessageType === "PackageInstallationCancelled") { + Dashboard.showPackageInstallNotification(msg.Data, "cancelled"); + Dashboard.refreshSystemInfoFromServer(); + } + else if (msg.MessageType === "PackageInstalling") { + Dashboard.showPackageInstallNotification(msg.Data, "progress"); + Dashboard.refreshSystemInfoFromServer(); + } + else if (msg.MessageType === "ScheduledTaskEndExecute") { + + Dashboard.showTaskCompletionNotification(msg.Data); + } + }, + + showTaskCompletionNotification: function (result) { + + var html = ''; + + if (result.Status == "Completed") { + html += ''; + return; + } + else if (result.Status == "Cancelled") { + html += ''; + return; + } + else { + html += ''; + } + + html += ''; + html += result.Name + " " + result.Status; + html += ''; + + var timeout = 0; + + if (result.Status == 'Cancelled') { + timeout = 2000; + } + + Dashboard.showFooterNotification({ html: html, id: result.Id, forceShow: true, timeout: timeout }); + }, + + showPackageInstallNotification: function (installation, status) { + + var html = ''; + + if (status == 'completed') { + html += ''; + } + else if (status == 'cancelled') { + html += ''; + } + else if (status == 'failed') { + html += ''; + } + else if (status == 'progress') { + html += ''; + } + + html += ''; + + if (status == 'completed') { + html += installation.Name + ' ' + installation.Version + ' installation completed'; + } + else if (status == 'cancelled') { + html += installation.Name + ' ' + installation.Version + ' installation was cancelled'; + } + else if (status == 'failed') { + html += installation.Name + ' ' + installation.Version + ' installation failed'; + } + else if (status == 'progress') { + html += 'Installing ' + installation.Name + ' ' + installation.Version; + } + + html += ''; + + if (status == 'progress') { + + var percentComplete = Math.round(installation.PercentComplete || 0); + + html += ''; + html += '' + percentComplete + '%'; + html += ''; + + if (percentComplete < 100) { + var btnId = "btnCancel" + installation.Id; + html += ''; + } + } + + var timeout = 0; + + if (status == 'cancelled') { + timeout = 2000; + } + + var forceShow = status != "progress"; + var allowHide = status != "progress" && status != 'cancelled'; + + Dashboard.showFooterNotification({ html: html, id: installation.Id, timeout: timeout, forceShow: forceShow, allowHide: allowHide }); + }, + + processLibraryUpdateNotification: function (data) { + + var newItems = data.ItemsAdded.filter(function (a) { + return !a.IsFolder; + }); + + if (!Dashboard.newItems) { + Dashboard.newItems = []; + } + + for (var i = 0, length = newItems.length ; i < length; i++) { + + Dashboard.newItems.push(newItems[i]); + } + + if (Dashboard.newItemTimeout) { + clearTimeout(Dashboard.newItemTimeout); + } + + Dashboard.newItemTimeout = setTimeout(Dashboard.onNewItemTimerStopped, 60000); + }, + + onNewItemTimerStopped: function () { + + var newItems = Dashboard.newItems; + + newItems = newItems.sort(function (a, b) { + + if (a.PrimaryImageTag && b.PrimaryImageTag) { + return 0; + } + + if (a.PrimaryImageTag) { + return -1; + } + + return 1; + }); + + Dashboard.newItems = []; + Dashboard.newItemTimeout = null; + + // Show at most 3 notifications + for (var i = 0, length = Math.min(newItems.length, 3) ; i < length; i++) { + + var item = newItems[i]; + + var data = { + title: "New " + item.Type, + body: item.Name, + timeout: 6000 + }; + + if (item.PrimaryImageTag) { + data.icon = ApiClient.getImageUrl(item.Id, { + width: 100, + tag: item.PrimaryImageTag, + type: "Primary" + }); + + if (!item.Id || data.icon.indexOf("undefined") != -1) { + alert("bad image url: " + JSON.stringify(item)); + console.log("bad image url: " + JSON.stringify(item)); + + continue; + } + } + + WebNotifications.show(data); + } + }, + + ensurePageTitle: function (page) { + + if (!page.hasClass('type-interior')) { + return; + } + + var pageElem = page[0]; + + if (pageElem.hasPageTitle) { + return; + } + + var parent = $('.content-primary', page); + + if (!parent.length) { + parent = $('.ui-content', page)[0]; + } + + $(parent).prepend("

    " + (document.title || " ") + "

    "); + + pageElem.hasPageTitle = true; + }, + + setPageTitle: function (title) { + + $('.pageTitle', $.mobile.activePage).html(title); + + if (title) { + document.title = title; + } + }, + + metroColors: ["#6FBD45", "#4BB3DD", "#4164A5", "#E12026", "#800080", "#E1B222", "#008040", "#0094FF", "#FF00C7", "#FF870F", "#7F0037"], + + getRandomMetroColor: function () { + + var index = Math.floor(Math.random() * (Dashboard.metroColors.length - 1)); + + return Dashboard.metroColors[index]; + } + +}; + +var ApiClient = MediaBrowser.ApiClient.create("Dashboard"); + +$(function () { + + var footerHtml = ''; + + + $(document.body).append(footerHtml); +}); + +Dashboard.jQueryMobileInit(); + +$(document).on('pagebeforeshow', ".page", function () { + + Dashboard.refreshSystemInfoFromServer(); + + var page = $(this); + + Dashboard.ensureHeader(page); + Dashboard.ensurePageTitle(page); + +}).on('pageinit', ".page", function () { + + var page = $(this); + + var userId = Dashboard.getCurrentUserId(); + ApiClient.currentUserId(userId); + + if (!userId) { + + if (this.id !== "loginPage" && !page.hasClass('wizardPage')) { + + Dashboard.logout(); + } + } + + else { + + Dashboard.getCurrentUser().done(function (user) { + + if (user.Configuration.IsAdministrator) { + Dashboard.ensureToolsMenu(page); + } + }); + } }); \ No newline at end of file diff --git a/Html/support.html b/dashboard-ui/support.html similarity index 100% rename from Html/support.html rename to dashboard-ui/support.html diff --git a/Html/supporter.html b/dashboard-ui/supporter.html similarity index 100% rename from Html/supporter.html rename to dashboard-ui/supporter.html diff --git a/Html/supporterKey.html b/dashboard-ui/supporterKey.html similarity index 100% rename from Html/supporterKey.html rename to dashboard-ui/supporterKey.html diff --git a/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons-v2.png b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons-v2.png similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons-v2.png rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons-v2.png diff --git a/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons.png b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons.png similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons.png rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons.png diff --git a/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.eot b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.eot similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.eot rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.eot diff --git a/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.ttf b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.ttf similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.ttf rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.ttf diff --git a/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.woff b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.woff similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.woff rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.woff diff --git a/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/ajax-loader.png b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/images/ajax-loader.png similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/ajax-loader.png rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/images/ajax-loader.png diff --git a/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-black-pack.png b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-black-pack.png similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-black-pack.png rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-black-pack.png diff --git a/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-white-pack.png b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-white-pack.png similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-white-pack.png rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-white-pack.png diff --git a/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-black-pack.png b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-black-pack.png similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-black-pack.png rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-black-pack.png diff --git a/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-white-pack.png b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-white-pack.png similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-white-pack.png rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-white-pack.png diff --git a/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/index.html b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/index.html similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/font-awesome/index.html rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/index.html diff --git a/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.css b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.css similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.css rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.css diff --git a/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.scss b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.scss similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.scss rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.scss diff --git a/Html/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.gif b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.gif similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.gif rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.gif diff --git a/Html/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.png b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.png similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.png rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.png diff --git a/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-black-pack.png b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-black-pack.png similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-black-pack.png rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-black-pack.png diff --git a/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-white-pack.png b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-white-pack.png similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-white-pack.png rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-white-pack.png diff --git a/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-black-pack.png b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-black-pack.png similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-black-pack.png rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-black-pack.png diff --git a/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-white-pack.png b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-white-pack.png similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-white-pack.png rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-white-pack.png diff --git a/Html/thirdparty/jqm-icon-pack-3.0/original/index.html b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/index.html similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/original/index.html rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/index.html diff --git a/Html/thirdparty/jqm-icon-pack-3.0/original/jqm-icon-pack-2.0-original.css b/dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/jqm-icon-pack-2.0-original.css similarity index 100% rename from Html/thirdparty/jqm-icon-pack-3.0/original/jqm-icon-pack-2.0-original.css rename to dashboard-ui/thirdparty/jqm-icon-pack-3.0/original/jqm-icon-pack-2.0-original.css diff --git a/Html/uiSettings.html b/dashboard-ui/uiSettings.html similarity index 100% rename from Html/uiSettings.html rename to dashboard-ui/uiSettings.html diff --git a/Html/updatePassword.html b/dashboard-ui/updatePassword.html similarity index 100% rename from Html/updatePassword.html rename to dashboard-ui/updatePassword.html diff --git a/Html/userImage.html b/dashboard-ui/userImage.html similarity index 100% rename from Html/userImage.html rename to dashboard-ui/userImage.html diff --git a/Html/userProfiles.html b/dashboard-ui/userProfiles.html similarity index 100% rename from Html/userProfiles.html rename to dashboard-ui/userProfiles.html diff --git a/Html/wizardFinish.html b/dashboard-ui/wizardFinish.html similarity index 100% rename from Html/wizardFinish.html rename to dashboard-ui/wizardFinish.html diff --git a/Html/wizardLibrary.html b/dashboard-ui/wizardLibrary.html similarity index 100% rename from Html/wizardLibrary.html rename to dashboard-ui/wizardLibrary.html diff --git a/Html/wizardStart.html b/dashboard-ui/wizardStart.html similarity index 100% rename from Html/wizardStart.html rename to dashboard-ui/wizardStart.html diff --git a/Html/wizardUser.html b/dashboard-ui/wizardUser.html similarity index 100% rename from Html/wizardUser.html rename to dashboard-ui/wizardUser.html