diff --git a/Html/addPlugin.html b/Html/addPlugin.html new file mode 100644 index 000000000..820319091 --- /dev/null +++ b/Html/addPlugin.html @@ -0,0 +1,80 @@ + + +
++ Plugin Catalog +
+ + + + ++ Version +
+ + ++
+ ++
+I'm the collapsible content. By default I'm closed, but you can click the header to open me.
+I'm the collapsible content. By default I'm closed, but you can click the header to open me.
+I'm the collapsible content. By default I'm closed, but you can click the header to open me.
+Below are your media collections. Expand a collection to add or remove media locations assigned to it.
++ +
+ ++ +
+Below are Media Browser's scheduled tasks. Click into a task to adjust it's schedule.
+There are no users currently connected.
'; + $('#divConnections', page).html(html).trigger('create'); + return; + } + + html += '| '; + html += DashboardPage.getClientType(connection); + html += ' | '; + + html += ''; + html += user.Name; + html += ' | '; + + html += ''; + html += connection.DeviceName; + html += ' | '; + + html += ''; + html += DashboardPage.getNowPlayingImage(connection.NowPlayingItem); + html += ' | '; + + html += ''; + html += DashboardPage.getNowPlayingText(connection, connection.NowPlayingItem); + html += ' | '; + + html += '
";
+ }
+ if (connection.ClientType == "Pc") {
+
+ return "
";
+ }
+ if (connection.ClientType == "Android") {
+
+ return "
";
+ }
+ if (connection.ClientType == "Ios") {
+
+ return "
";
+ }
+ if (connection.ClientType == "WindowsRT") {
+
+ return "
";
+ }
+ if (connection.ClientType == "WindowsPhone") {
+
+ return "
";
+ }
+
+ return connection.ClientType;
+ },
+
+ getNowPlayingImage: function (item) {
+
+ if (item) {
+
+ if (item.BackdropImageTag) {
+ var url = ApiClient.getImageUrl(item.Id, {
+ type: "Backdrop",
+ height: 100,
+ tag: item.BackdropImageTag
+ });
+
+ return "No tasks are currently running.
'; + } + + for (var i = 0, length = dashboardInfo.RunningTasks.length; i < length; i++) { + + + var task = dashboardInfo.RunningTasks[i]; + + html += ''; + + html += task.Name; + + if (task.State == "Running") { + var progress = task.CurrentProgress || { PercentComplete: 0 }; + html += ' - ' + Math.round(progress.PercentComplete) + '%'; + + html += ''; + } + else if (task.State == "Cancelling") { + html += ' - Stopping'; + } + + html += '
'; + } + + + $('#divRunningTasks', page).html(html).trigger('create'); + }, + + renderSystemInfo: function (dashboardInfo) { + + Dashboard.updateSystemInfo(dashboardInfo.SystemInfo); + + var page = $.mobile.activePage; + + $('#appVersionNumber', page).html(dashboardInfo.SystemInfo.Version); + + if (dashboardInfo.RunningTasks.filter(function (task) { + + return task.Id == dashboardInfo.ApplicationUpdateTaskId; + + }).length) { + + $('#btnUpdateApplication', page).button('disable'); + } else { + $('#btnUpdateApplication', page).button('enable'); + } + + DashboardPage.renderApplicationUpdateInfo(dashboardInfo); + DashboardPage.renderPluginUpdateInfo(dashboardInfo); + }, + + renderApplicationUpdateInfo: function (dashboardInfo) { + + var page = $.mobile.activePage; + + if (dashboardInfo.SystemInfo.IsNetworkDeployed && !dashboardInfo.SystemInfo.HasPendingRestart) { + + // Only check once every 10 mins + if (DashboardPage.lastAppUpdateCheck && (new Date().getTime() - DashboardPage.lastAppUpdateCheck) < 600000) { + return; + } + + DashboardPage.lastAppUpdateCheck = new Date().getTime(); + + ApiClient.getAvailableApplicationUpdate().done(function (packageInfo) { + + var version = packageInfo.versions[0]; + + if (!version) { + $('#pUpToDate', page).show(); + $('#pUpdateNow', page).hide(); + } else { + $('#pUpToDate', page).hide(); + + $('#pUpdateNow', page).show(); + + $('#newVersionNumber', page).html("Version " + version.versionStr + " is now available for download."); + } + + }).fail(function () { + + Dashboard.showFooterNotification({ html: '
There was an error connecting to the remote Media Browser repository.', id: "MB3ConnectionError" });
+
+ });
+
+ } else {
+
+ if (dashboardInfo.SystemInfo.HasPendingRestart) {
+ $('#pUpToDate', page).hide();
+ } else {
+ $('#pUpToDate', page).show();
+ }
+
+ $('#pUpdateNow', page).hide();
+ }
+ },
+
+ renderPluginUpdateInfo: function (dashboardInfo) {
+
+ // Only check once every 10 mins
+ if (DashboardPage.lastPluginUpdateCheck && (new Date().getTime() - DashboardPage.lastPluginUpdateCheck) < 600000) {
+ return;
+ }
+
+ DashboardPage.lastPluginUpdateCheck = new Date().getTime();
+
+ var page = $.mobile.activePage;
+
+ ApiClient.getAvailablePluginUpdates().done(function (updates) {
+
+ if (updates.length) {
+
+ $('#collapsiblePluginUpdates', page).show();
+
+ } else {
+ $('#collapsiblePluginUpdates', page).hide();
+
+ return;
+ }
+ var html = '';
+
+ for (var i = 0, length = updates.length; i < length; i++) {
+
+ var update = updates[i];
+
+ html += 'A new version of ' + update.name + ' is available!
'; + + html += ''; + } + + $('#pPluginUpdates', page).html(html).trigger('create'); + + }).fail(function () { + + Dashboard.showFooterNotification({ html: '
There was an error connecting to the remote Media Browser repository.', id: "MB3ConnectionError" });
+
+ });
+ },
+
+ installPluginUpdate: function (button) {
+
+ $(button).button('disable');
+
+ var name = button.getAttribute('data-name');
+ var version = button.getAttribute('data-version');
+ var classification = button.getAttribute('data-classification');
+
+ Dashboard.showLoadingMsg();
+
+ ApiClient.installPlugin(name, classification, version).done(function () {
+
+ Dashboard.hideLoadingMsg();
+ });
+ },
+
+ updateApplication: function () {
+
+ var page = $.mobile.activePage;
+ $('#btnUpdateApplication', page).button('disable');
+
+ Dashboard.showLoadingMsg();
+
+ ApiClient.startScheduledTask(DashboardPage.lastDashboardInfo.ApplicationUpdateTaskId).done(function () {
+
+ DashboardPage.pollForInfo();
+
+ Dashboard.hideLoadingMsg();
+ });
+ },
+
+ stopTask: function (id) {
+
+ ApiClient.stopScheduledTask(id).done(function () {
+
+ DashboardPage.pollForInfo();
+ });
+
+ }
+};
+
+$(document).on('pageshow', "#dashboardPage", DashboardPage.onPageShow).on('pagehide', "#dashboardPage", DashboardPage.onPageHide);
\ No newline at end of file
diff --git a/Html/scripts/DisplaySettingsPage.js b/Html/scripts/DisplaySettingsPage.js
new file mode 100644
index 000000000..da87a106f
--- /dev/null
+++ b/Html/scripts/DisplaySettingsPage.js
@@ -0,0 +1,46 @@
+var DisplaySettingsPage = {
+
+ onPageShow: function () {
+ Dashboard.showLoadingMsg();
+
+ var page = this;
+
+ ApiClient.getServerConfiguration().done(function (config) {
+
+ $('#txtWeatherLocation', page).val(config.WeatherLocation);
+ $('#txtMinResumePct', page).val(config.MinResumePct);
+ $('#txtMaxResumePct', page).val(config.MaxResumePct);
+ $('#txtMinResumeDuration', page).val(config.MinResumeDurationSeconds);
+ $('#selectWeatherUnit', page).val(config.WeatherUnit).selectmenu("refresh");
+
+ Dashboard.hideLoadingMsg();
+ });
+
+ },
+
+ submit: function() {
+
+ $('.btnSubmit', $.mobile.activePage)[0].click();
+
+ },
+
+ onSubmit: function () {
+ var form = this;
+
+ ApiClient.getServerConfiguration().done(function (config) {
+
+ config.WeatherLocation = $('#txtWeatherLocation', form).val();
+ config.WeatherUnit = $('#selectWeatherUnit', form).val();
+ config.MinResumePct = $('#txtMinResumePct', form).val();
+ config.MaxResumePct = $('#txtMaxResumePct', form).val();
+ config.MinResumeDurationSeconds = $('#txtMinResumeDuration', form).val();
+
+ ApiClient.updateServerConfiguration(config);
+ });
+
+ // Disable default form submission
+ return false;
+ }
+};
+
+$(document).on('pageshow', "#displaySettingsPage", DisplaySettingsPage.onPageShow);
diff --git a/Html/scripts/EditUserPage.js b/Html/scripts/EditUserPage.js
new file mode 100644
index 000000000..0d362e5de
--- /dev/null
+++ b/Html/scripts/EditUserPage.js
@@ -0,0 +1,175 @@
+var EditUserPage = {
+
+ onPageShow: function () {
+ Dashboard.showLoadingMsg();
+
+ var userId = getParameterByName("userId");
+
+ if (userId) {
+ $('#userProfileNavigation', this).show();
+ } else {
+ $('#userProfileNavigation', this).hide();
+ }
+
+ var promise4 = ApiClient.getCultures();
+
+ var promise3 = ApiClient.getParentalRatings();
+
+ var promise1;
+
+ if (!userId) {
+
+ var deferred = $.Deferred();
+
+ deferred.resolveWith(null, [{
+ Configuration: {}
+ }]);
+
+ promise1 = deferred.promise();
+ } else {
+
+ promise1 = ApiClient.getUser(userId);
+ }
+
+ var promise2 = Dashboard.getCurrentUser();
+
+ $.when(promise1, promise2, promise3, promise4).done(function (response1, response2, response3, response4) {
+
+ EditUserPage.loadUser(response1[0] || response1, response2[0], response3[0], response4[0]);
+
+ });
+ },
+
+ loadUser: function (user, loggedInUser, allParentalRatings, allCultures) {
+
+ var page = $($.mobile.activePage);
+
+ EditUserPage.populateLanguages($('#selectAudioLanguage', page), allCultures);
+ EditUserPage.populateLanguages($('#selectSubtitleLanguage', page), allCultures);
+ EditUserPage.populateRatings(allParentalRatings, page);
+
+ if (!loggedInUser.Configuration.IsAdministrator || user.Id == loggedInUser.Id) {
+
+ $('#fldIsAdmin', page).hide();
+ $('#fldMaxParentalRating', page).hide();
+ } else {
+ $('#fldIsAdmin', page).show();
+ $('#fldMaxParentalRating', page).show();
+ }
+
+ Dashboard.setPageTitle(user.Name || "Add User");
+
+ $('#txtUserName', page).val(user.Name);
+
+ var ratingValue = "";
+
+ if (user.Configuration.MaxParentalRating) {
+
+ for (var i = 0, length = allParentalRatings.length; i < length; i++) {
+
+ var rating = allParentalRatings[i];
+
+ if (user.Configuration.MaxParentalRating >= rating.Value) {
+ ratingValue = rating.Value;
+ }
+ }
+ }
+
+ $('#selectMaxParentalRating', page).val(ratingValue).selectmenu("refresh");
+
+ $('#selectAudioLanguage', page).val(user.Configuration.AudioLanguagePreference || "").selectmenu("refresh");
+ $('#selectSubtitleLanguage', page).val(user.Configuration.SubtitleLanguagePreference || "").selectmenu("refresh");
+
+ $('#chkForcedSubtitlesOnly', page).checked(user.Configuration.UseForcedSubtitlesOnly || false).checkboxradio("refresh");
+ $('#chkIsAdmin', page).checked(user.Configuration.IsAdministrator || false).checkboxradio("refresh");
+
+ Dashboard.hideLoadingMsg();
+ },
+
+ populateLanguages: function (select, allCultures) {
+
+ var html = "";
+
+ html += "";
+
+ for (var i = 0, length = allCultures.length; i < length; i++) {
+
+ var culture = allCultures[i];
+
+ html += "";
+ }
+
+ select.html(html).selectmenu("refresh");
+ },
+
+ populateRatings: function (allParentalRatings, page) {
+
+ var html = "";
+
+ html += "";
+
+ for (var i = 0, length = allParentalRatings.length; i < length; i++) {
+
+ var rating = allParentalRatings[i];
+
+ html += "";
+ }
+
+ $('#selectMaxParentalRating', page).html(html).selectmenu("refresh");
+ },
+
+ saveUser: function (user) {
+
+ var page = $($.mobile.activePage);
+
+ user.Name = $('#txtUserName', page).val();
+ user.Configuration.MaxParentalRating = $('#selectMaxParentalRating', page).val() || null;
+
+ user.Configuration.IsAdministrator = $('#chkIsAdmin', page).checked();
+
+ user.Configuration.AudioLanguagePreference = $('#selectAudioLanguage', page).val();
+ user.Configuration.SubtitleLanguagePreference = $('#selectSubtitleLanguage', page).val();
+ user.Configuration.UseForcedSubtitlesOnly = $('#chkForcedSubtitlesOnly', page).checked();
+
+ var userId = getParameterByName("userId");
+
+ if (userId) {
+ ApiClient.updateUser(user).done(EditUserPage.saveComplete);
+ } else {
+ ApiClient.createUser(user).done(EditUserPage.saveComplete);
+ }
+ },
+
+ saveComplete: function () {
+ Dashboard.hideLoadingMsg();
+
+ var userId = getParameterByName("userId");
+
+ Dashboard.validateCurrentUser();
+
+ if (userId) {
+ Dashboard.alert("Settings saved.");
+ } else {
+ Dashboard.navigate("userProfiles.html");
+ }
+ },
+
+ onSubmit: function () {
+ Dashboard.showLoadingMsg();
+
+ var userId = getParameterByName("userId");
+
+ if (!userId) {
+ EditUserPage.saveUser({
+ Configuration: {}
+ });
+ } else {
+ ApiClient.getUser(userId).done(EditUserPage.saveUser);
+ }
+
+ // Disable default form submission
+ return false;
+ }
+};
+
+$(document).on('pageshow', "#editUserPage", EditUserPage.onPageShow);
diff --git a/Html/scripts/Extensions.js b/Html/scripts/Extensions.js
new file mode 100644
index 000000000..dba43a704
--- /dev/null
+++ b/Html/scripts/Extensions.js
@@ -0,0 +1,333 @@
+// Array Remove - By John Resig (MIT Licensed)
+Array.prototype.remove = function (from, to) {
+ var rest = this.slice((to || from) + 1 || this.length);
+ this.length = from < 0 ? this.length + from : from;
+ return this.push.apply(this, rest);
+};
+
+String.prototype.endsWith = function (suffix) {
+ return this.indexOf(suffix, this.length - suffix.length) !== -1;
+};
+
+$.fn.checked = function (value) {
+ if (value === true || value === false) {
+ // Set the value of the checkbox
+ return $(this).each(function () {
+ this.checked = value;
+ });
+ } else {
+ // Return check state
+ return $(this).is(':checked');
+ }
+};
+
+var WebNotifications = {
+
+ show: function (data) {
+ if (window.webkitNotifications) {
+ if (!webkitNotifications.checkPermission()) {
+ var notif = webkitNotifications.createNotification(data.icon, data.title, data.body);
+ notif.show();
+
+ if (data.timeout) {
+ setTimeout(function () {
+ notif.cancel();
+ }, data.timeout);
+ }
+
+ return notif;
+ } else {
+ webkitNotifications.requestPermission(function () {
+ return WebNotifications.show(data);
+ });
+ }
+ }
+ else if (window.Notification) {
+ if (Notification.permissionLevel() === "granted") {
+ var notif = new Notification(data.title, data);
+ notif.show();
+
+ if (data.timeout) {
+ setTimeout(function () {
+ notif.cancel();
+ }, data.timeout);
+ }
+
+ return notif;
+ } else if (Notification.permissionLevel() === "default") {
+ Notification.requestPermission(function () {
+ return WebNotifications.show(data);
+ });
+ }
+ }
+ },
+
+ requestPermission: function () {
+ if (window.webkitNotifications) {
+ if (!webkitNotifications.checkPermission()) {
+ } else {
+ webkitNotifications.requestPermission(function () {
+ });
+ }
+ }
+ else if (window.Notification) {
+ if (Notification.permissionLevel() === "granted") {
+ } else if (Notification.permissionLevel() === "default") {
+ Notification.requestPermission(function () {
+ });
+ }
+ }
+ }
+};
+
+/*
+ * Javascript Humane Dates
+ * Copyright (c) 2008 Dean Landolt (deanlandolt.com)
+ * Re-write by Zach Leatherman (zachleat.com)
+ *
+ * Adopted from the John Resig's pretty.js
+ * at http://ejohn.org/blog/javascript-pretty-date
+ * and henrah's proposed modification
+ * at http://ejohn.org/blog/javascript-pretty-date/#comment-297458
+ *
+ * Licensed under the MIT license.
+ */
+
+function humane_date(date_str) {
+ var time_formats = [[90, 'a minute'], // 60*1.5
+ [3600, 'minutes', 60], // 60*60, 60
+ [5400, 'an hour'], // 60*60*1.5
+ [86400, 'hours', 3600], // 60*60*24, 60*60
+ [129600, 'a day'], // 60*60*24*1.5
+ [604800, 'days', 86400], // 60*60*24*7, 60*60*24
+ [907200, 'a week'], // 60*60*24*7*1.5
+ [2628000, 'weeks', 604800], // 60*60*24*(365/12), 60*60*24*7
+ [3942000, 'a month'], // 60*60*24*(365/12)*1.5
+ [31536000, 'months', 2628000], // 60*60*24*365, 60*60*24*(365/12)
+ [47304000, 'a year'], // 60*60*24*365*1.5
+ [3153600000, 'years', 31536000] // 60*60*24*365*100, 60*60*24*365
+ ];
+
+ var dt = new Date;
+ var date = parseISO8601Date(date_str, true);
+
+ var seconds = ((dt - date) / 1000);
+ var token = ' ago';
+ var i = 0;
+ var format;
+
+ if (seconds < 0) {
+ seconds = Math.abs(seconds);
+ token = '';
+ }
+
+ while (format = time_formats[i++]) {
+ if (seconds < format[0]) {
+ if (format.length == 2) {
+ return format[1] + token;
+ } else {
+ return Math.round(seconds / format[2]) + ' ' + format[1] + token;
+ }
+ }
+ }
+
+ // overflow for centuries
+ if (seconds > 4730400000)
+ return Math.round(seconds / 4730400000) + ' centuries' + token;
+
+ return date_str;
+};
+
+function humane_elapsed(firstDateStr, secondDateStr) {
+ var dt1 = new Date(firstDateStr);
+ var dt2 = new Date(secondDateStr);
+ var seconds = (dt2.getTime() - dt1.getTime()) / 1000;
+ var numdays = Math.floor((seconds % 31536000) / 86400);
+ var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600);
+ var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60);
+ var numseconds = Math.round((((seconds % 31536000) % 86400) % 3600) % 60);
+
+ var elapsedStr = '';
+ elapsedStr += numdays == 1 ? numdays + ' day ' : '';
+ elapsedStr += numdays > 1 ? numdays + ' days ' : '';
+ elapsedStr += numhours == 1 ? numhours + ' hour ' : '';
+ elapsedStr += numhours > 1 ? numhours + ' hours ' : '';
+ elapsedStr += numminutes == 1 ? numminutes + ' minute ' : '';
+ elapsedStr += numminutes > 1 ? numminutes + ' minutes ' : '';
+ elapsedStr += elapsedStr.length > 0 ? 'and ' : '';
+ elapsedStr += numseconds == 1 ? numseconds + ' second' : '';
+ elapsedStr += numseconds == 0 || numseconds > 1 ? numseconds + ' seconds' : '';
+
+ return elapsedStr;
+
+}
+
+function getParameterByName(name) {
+ name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
+ var regexS = "[\\?&]" + name + "=([^]*)";
+ var regex = new RegExp(regexS);
+ var results = regex.exec(window.location.search);
+ if (results == null)
+ return "";
+ else
+ return decodeURIComponent(results[1].replace(/\+/g, " "));
+}
+
+function parseISO8601Date(s, toLocal) {
+
+ // parenthese matches:
+ // year month day hours minutes seconds
+ // dotmilliseconds
+ // tzstring plusminus hours minutes
+ var re = /(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d+)?(Z|([+-])(\d\d):(\d\d))/;
+
+ var d = [];
+ d = s.match(re);
+
+ // "2010-12-07T11:00:00.000-09:00" parses to:
+ // ["2010-12-07T11:00:00.000-09:00", "2010", "12", "07", "11",
+ // "00", "00", ".000", "-09:00", "-", "09", "00"]
+ // "2010-12-07T11:00:00.000Z" parses to:
+ // ["2010-12-07T11:00:00.000Z", "2010", "12", "07", "11",
+ // "00", "00", ".000", "Z", undefined, undefined, undefined]
+
+ if (!d) {
+ throw "Couldn't parse ISO 8601 date string '" + s + "'";
+ }
+
+ // parse strings, leading zeros into proper ints
+ var a = [1, 2, 3, 4, 5, 6, 10, 11];
+ for (var i in a) {
+ d[a[i]] = parseInt(d[a[i]], 10);
+ }
+ d[7] = parseFloat(d[7]);
+
+ // Date.UTC(year, month[, date[, hrs[, min[, sec[, ms]]]]])
+ // note that month is 0-11, not 1-12
+ // see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/UTC
+ var ms = Date.UTC(d[1], d[2] - 1, d[3], d[4], d[5], d[6]);
+
+ // if there are milliseconds, add them
+ if (d[7] > 0) {
+ ms += Math.round(d[7] * 1000);
+ }
+
+ // if there's a timezone, calculate it
+ if (d[8] != "Z" && d[10]) {
+ var offset = d[10] * 60 * 60 * 1000;
+ if (d[11]) {
+ offset += d[11] * 60 * 1000;
+ }
+ if (d[9] == "-") {
+ ms -= offset;
+ } else {
+ ms += offset;
+ }
+ } else if (!toLocal) {
+ ms += new Date().getTimezoneOffset() * 60000;
+ }
+
+ return new Date(ms);
+};
+
+
+
+// jqm.page.params.js - version 0.1
+// Copyright (c) 2011, Kin Blas
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the
';
+ }
+
+ html += '' + user.Name + '
'; + html += '' + LoginPage.getLastSeenText(user.LastActivityDate) + '
'; + html += ''; + html += ''; + html += ''; + html += '
'; + + html += '" + plugin.Version + "
"; + + html += ""; + + if (!plugin.IsCorePlugin) { + html += "Delete"; + } + + html += "" + text + "
"; + } + + html += "Start"; + } + else if (task.State == "Running") { + + var progress = task.CurrentProgress || { PercentComplete: 0 }; + progress = Math.round(progress.PercentComplete); + + html += ''; + + html += "" + progress + "%"; + html += '
'; + + html += "Stop"; + + } else { + + html += "Stopping
"; + html += ""; + } + + html += ""; + + html += "
";
+ }
+
+ 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 = '';
+
+ 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 (pluginSecurityInfo.IsMBSupporter) {
+ headerHtml += '
';
+ }
+ if (user.Configuration.IsAdministrator) {
+ headerHtml += '
';
+ }
+
+ headerHtml += '
';
+ 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
+ });
+ }
+
+ 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("+ Media Browser has a thriving community of users and a vast knowledge base of information to help you get the most + out of your media collection. +
++ The Community Tracker is a place where you can ask questions, post feature requests and report bugs and get timely + and friendly help from a thriving community of users and developers. +
+ Visit the Community Tracker ++ Also, within the tracker, there is a large Knowledge Base of information compiled from users and developers to help you get the + most out of Media Browser. +
+ Search the Knowledge Base ++ Finally, you can visit the Media Browser Web site to see what's happening with MB now and keep up with the developer blog. +
+ Visit the Media Browser Web Site ++ By becoming a Media Browser Supporter, you ensure the continued development and support of this product and open up a whole new world of premium plug-ins. +
++ A portion of all MB3 Supporter donations is also contributed to some of our metadata providers (The Movie Db, + The TVdb, and FanArt.tv) +
++ Premium plug-ins can be installed and used for their trial periods (14 days on any particular machine) but, to register them for use + beyond that period, you also have to be a Media Browser Supporter. + +
+ + + ++ Glyphs courtesy of FontAwesome +
+ +© 2013 - Andy Matthews
+© 2013 - Andy Matthews
++ +
+ +
You're Done!That's all we need for now. Media Browser has begun collecting information about your media library. You do not need to wait for this process to complete before using a client application or changing other settings within the Dashboard.
+ + +
Media LibraryBelow are your media collections. Expand a collection to add or remove media locations assigned to it.
++ +
+ +
Welcome to Media Browser Server!This wizard will help guide you through the setup process.
+ +