diff --git a/ApiClient.js b/ApiClient.js
index f3b24cd29..1d2d18006 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 c47c07541..000000000
--- 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 47ff3b0c1..1e095281f 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 699ad6143..3621e341b 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 133eb34fb..bed60ac1f 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 928fb06b6..8b3043ba5 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 1a0a26d63..5ef9ed500 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 27dc97810..82f0f21d3 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 = $('
';
-
- var imageUrl = user.PrimaryImageTag ? ApiClient.getUserImageUrl(user.Id, {
-
- height: 400,
- tag: user.PrimaryImageTag,
- type: "Primary"
-
- }) : "css/images/userFlyoutDefault.png";
-
- html += '';
- html += '
';
- }
- else if (isLibraryPage) {
-
- headerHtml += '
';
- }
- headerHtml += '';
-
- var imageColor = isLibraryPage ? "White" : "Black";
-
- if (user && !page.hasClass('wizardPage')) {
- headerHtml += '
';
- }
- headerHtml += '';
-
- if (user.Configuration.IsAdministrator) {
- headerHtml += '
';
- }
-
- headerHtml += '
').insertBefore('.btnTools', page);
- }
- });
- },
-
- ensureToolsMenu: function (page) {
-
- if (!page.hasClass('type-interior')) {
- return;
- }
-
- var sidebar = $('.toolsSidebar', page);
-
- if (!sidebar.length) {
-
- var 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 += '';
-
- 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("
';
+
+ 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 = '';
+
+ var imageUrl = user.PrimaryImageTag ? ApiClient.getUserImageUrl(user.Id, {
+
+ height: 400,
+ tag: user.PrimaryImageTag,
+ type: "Primary"
+
+ }) : "css/images/userFlyoutDefault.png";
+
+ html += '';
+ html += '
';
+ }
+ else if (isLibraryPage) {
+
+ headerHtml += '
';
+ }
+ headerHtml += '';
+
+ var imageColor = isLibraryPage ? "White" : "Black";
+
+ if (user && !page.hasClass('wizardPage')) {
+ headerHtml += '
';
+ }
+ headerHtml += '';
+
+ if (user.Configuration.IsAdministrator) {
+ headerHtml += '
';
+ }
+
+ headerHtml += '
').insertBefore('.btnTools', page);
+ }
+ });
+ },
+
+ ensureToolsMenu: function (page) {
+
+ if (!page.hasClass('type-interior')) {
+ return;
+ }
+
+ var sidebar = $('.toolsSidebar', page);
+
+ if (!sidebar.length) {
+
+ var 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 += '';
+
+ 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("