1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

copy dashboard to the output folder and load from the file system, instead of using embedded resources

This commit is contained in:
Luke Pulverenti 2013-03-23 00:04:36 -04:00
parent 799eebc9ed
commit 4dd9477bcd
137 changed files with 1424 additions and 1438 deletions

View file

@ -0,0 +1,249 @@
var AddPluginPage = {
onPageShow: function () {
var page = this;
Dashboard.showLoadingMsg();
var name = getParameterByName('name');
var promise1 = ApiClient.getPackageInfo(name);
var promise2 = ApiClient.getInstalledPlugins();
var promise3 = ApiClient.getPluginSecurityInfo();
$.when(promise1, promise2, promise3).done(function (response1, response2, response3) {
AddPluginPage.renderPackage(response1[0], response2[0], response3[0], page);
});
},
renderPackage: function (pkg, installedPlugins, pluginSecurityInfo, page) {
var installedPlugin = installedPlugins.filter(function (ip) {
return ip.Name == pkg.name;
})[0];
AddPluginPage.populateVersions(pkg, page, installedPlugin);
AddPluginPage.populateHistory(pkg);
Dashboard.setPageTitle(pkg.name);
if (pkg.shortDescription) {
$('#tagline', page).show().html(pkg.shortDescription);
} else {
$('#tagline', page).hide();
}
$('#overview', page).html(pkg.overview || "");
$('#developer', page).html(pkg.owner);
if (pkg.isPremium) {
$('.premiumPackage', page).show();
// Fill in registration info
var regStatus = "<strong>";
if (pkg.isRegistered) {
regStatus += "You are currently registered for this feature";
} else {
if (new Date(pkg.expDate).getTime() < new Date(1970, 1, 1).getTime()) {
regStatus += "This feature has no registration information";
} else {
if (new Date(pkg.expDate).getTime() <= new Date().getTime()) {
regStatus += "The trial period for this feature has expired";
} else {
regStatus += "The trial period for this feature will expire in " + Math.round((new Date(pkg.expDate).getTime() - new Date().getTime()) / (86400000)) + " day(s)";
}
}
}
regStatus += "</strong>";
$('#regStatus', page).html(regStatus);
if (pluginSecurityInfo.IsMBSupporter) {
$('#regInfo', page).html(pkg.regInfo || "");
if (pkg.price > 0) {
// Fill in PayPal info
$('premiumHasPrice', page).show();
$('#featureId', page).val(pkg.featureId);
$('#featureName', page).val(pkg.name);
$('#amount', page).val(pkg.price);
$('#regPrice', page).html("<h2>Price: $" + pkg.price.toFixed(2) + " (USD)</h2>");
var url = "http://mb3admin.com/admin/service/user/getPayPalEmail?id=" + pkg.owner;
$.getJSON(url).done(function(dev) {
if (dev.payPalEmail) {
$('#payPalEmail', page).val(dev.payPalEmail);
} else {
$('#ppButton', page).hide();
$('#noEmail', page).show();
}
});
} else {
// Supporter-only feature
$('premiumHasPrice', page).hide();
}
} else {
$('#regInfo', page).html("<h3>You must be a <a href='supporter.html'>Media Browser Supporter</a> in order to gain access to this feature.</h3>");
$('#ppButton', page).hide();
}
} else {
$('.premiumPackage', page).hide();
}
if (pkg.richDescUrl) {
$('#pViewWebsite', page).show();
$('#pViewWebsite a', page)[0].href = pkg.richDescUrl;
} else {
$('#pViewWebsite', page).hide();
}
if (pkg.previewImage) {
var color = pkg.tileColor || "#2572EB";
var img = pkg.previewImage ? pkg.previewImage : pkg.thumbImage;
$('#pPreviewImage', page).show().html("<img src='" + img + "' style='max-width: 100%;border-radius:10px;-moz-box-shadow: 0 0 20px 3px " + color + ";-webkit-box-shadow: 0 0 20px 3px " + color + ";box-shadow: 0 0 20px 3px " + color + ";' />");
} else {
$('#pPreviewImage', page).hide().html("");
}
if (installedPlugin) {
$('#pCurrentVersion', page).show().html("You currently have version <strong>" + installedPlugin.Version + "</strong> installed.");
} else {
$('#pCurrentVersion', page).hide().html("");
}
Dashboard.hideLoadingMsg();
},
populateVersions: function (packageInfo, page, installedPlugin) {
var html = '';
for (var i = 0, length = packageInfo.versions.length; i < length; i++) {
var version = packageInfo.versions[i];
html += '<option value="' + version.versionStr + '|' + version.classification + '">' + version.versionStr + ' (' + version.classification + ')</option>';
}
var selectmenu = $('#selectVersion', page).html(html);
var packageVersion;
if (installedPlugin) {
// Select the first available package with the same update class as the installed version
packageVersion = packageInfo.versions.filter(function (current) {
return current.classification == installedPlugin.UpdateClass;
})[0];
} else {
$('#pCurrentVersion', page).hide().html("");
}
// If we don't have a package version to select, pick the first release build
if (!packageVersion) {
// Select the first available package with the same update class as the installed version
packageVersion = packageInfo.versions.filter(function (current) {
return current.classification == "Release";
})[0];
}
// If we still don't have a package version to select, pick the first Beta build
if (!packageVersion) {
// Select the first available package with the same update class as the installed version
packageVersion = packageInfo.versions.filter(function (current) {
return current.classification == "Beta";
})[0];
}
if (packageVersion) {
var val = packageVersion.versionStr + '|' + packageVersion.classification;
$('#selectVersion', page).val(val);
}
selectmenu.selectmenu('refresh');
},
populateHistory: function (packageInfo) {
var html = '';
for (var i = 0, length = Math.min(packageInfo.versions.length, 10) ; i < length; i++) {
var version = packageInfo.versions[i];
html += '<h2 style="margin:.5em 0;">' + version.versionStr + ' (' + version.classification + ')</h2>';
html += '<div style="margin-bottom:1.5em;">' + version.description + '</div>';
}
$('#revisionHistory', $.mobile.activePage).html(html);
},
onSubmit: function () {
Dashboard.showLoadingMsg();
$('#btnInstall', $.mobile.activePage).button('disable');
var name = getParameterByName('name');
ApiClient.getInstalledPlugins().done(function (plugins) {
var installedPlugin = plugins.filter(function (ip) {
return ip.Name == name;
})[0];
var vals = $('#selectVersion', $.mobile.activePage).val().split('|');
var version = vals[0];
if (installedPlugin && installedPlugin.Version == version) {
Dashboard.hideLoadingMsg();
Dashboard.confirm("Are you sure you wish to reinstall the same version you already have? In most cases this will not have any effect.", "Plugin Reinstallation", function (confirmResult) {
if (confirmResult) {
Dashboard.showLoadingMsg();
AddPluginPage.performInstallation(name, vals[1], version);
} else {
$('#btnInstall', $.mobile.activePage).button('enable');
}
});
} else {
AddPluginPage.performInstallation(name, vals[1], version);
}
});
return false;
},
performInstallation: function (packageName, updateClass, version) {
ApiClient.installPlugin(packageName, updateClass, version).done(function () {
Dashboard.hideLoadingMsg();
});
}
};
$(document).on('pageshow', "#addPluginPage", AddPluginPage.onPageShow);

View file

@ -0,0 +1,65 @@
var AdvancedConfigurationPage = {
onPageShow: function () {
Dashboard.showLoadingMsg();
var promise1 = ApiClient.getServerConfiguration();
var promise2 = ApiClient.getSystemInfo();
$.when(promise1, promise2).done(function (response1, response2) {
AdvancedConfigurationPage.loadPage(response1[0], response2[0]);
});
},
loadPage: function (config, systemInfo) {
var page = $.mobile.activePage;
if (systemInfo.SupportsNativeWebSocket) {
$('#fldWebSocketPortNumber', page).hide();
} else {
$('#fldWebSocketPortNumber', page).show();
}
$('#selectAutomaticUpdateLevel', page).val(config.SystemUpdateLevel).selectmenu('refresh');
$('#txtWebSocketPortNumber', page).val(config.LegacyWebSocketPortNumber);
$('#txtPortNumber', page).val(config.HttpServerPortNumber);
$('#chkDebugLog', page).checked(config.EnableDebugLevelLogging).checkboxradio("refresh");
$('#chkEnableDeveloperTools', page).checked(config.EnableDeveloperTools).checkboxradio("refresh");
$('#chkRunAtStartup', page).checked(config.RunAtStartup).checkboxradio("refresh");
Dashboard.hideLoadingMsg();
},
onSubmit: function () {
Dashboard.showLoadingMsg();
var form = this;
ApiClient.getServerConfiguration().done(function (config) {
config.LegacyWebSocketPortNumber = $('#txtWebSocketPortNumber', form).val();
config.HttpServerPortNumber = $('#txtPortNumber', form).val();
config.EnableDebugLevelLogging = $('#chkDebugLog', form).checked();
config.EnableDeveloperTools = $('#chkEnableDeveloperTools', form).checked();
config.RunAtStartup = $('#chkRunAtStartup', form).checked();
config.SystemUpdateLevel = $('#selectAutomaticUpdateLevel', form).val();
ApiClient.updateServerConfiguration(config).done(Dashboard.processServerConfigurationUpdateResult);
});
// Disable default form submission
return false;
}
};
$(document).on('pageshow', "#advancedConfigurationPage", AdvancedConfigurationPage.onPageShow);

View file

@ -0,0 +1,69 @@
var AdvancedMetadataConfigurationPage = {
onPageShow: function () {
Dashboard.showLoadingMsg();
var page = this;
var promise1 = ApiClient.getServerConfiguration();
var promise2 = ApiClient.getItemTypes({ HasInternetProvider: true });
$.when(promise1, promise2).done(function (response1, response2) {
AdvancedMetadataConfigurationPage.load(page, response1[0], response2[0]);
});
},
load: function (page, config, itemTypes) {
AdvancedMetadataConfigurationPage.loadItemTypes(page, config, itemTypes);
Dashboard.hideLoadingMsg();
},
loadItemTypes: function (page, configuration, types) {
var html = '<div data-role="controlgroup">';
for (var i = 0, length = types.length; i < length; i++) {
var type = types[i];
var id = "checkbox-" + i + "a";
var checkedAttribute = configuration.InternetProviderExcludeTypes.indexOf(type) != -1 ? ' checked="checked"' : '';
html += '<input' + checkedAttribute + ' class="chkItemType" data-itemtype="' + type + '" type="checkbox" name="' + id + '" id="' + id + '" onchange="AdvancedMetadataConfigurationPage.submit();" />';
html += '<label for="' + id + '">' + type + '</label>';
}
html += "</div>";
$('#divItemTypes', page).html(html).trigger("create");
},
submit: function () {
$('.btnSubmit', $.mobile.activePage)[0].click();
},
onSubmit: function () {
var form = this;
ApiClient.getServerConfiguration().done(function (config) {
config.InternetProviderExcludeTypes = $.map($('.chkItemType:checked', form), function (currentCheckbox) {
return currentCheckbox.getAttribute('data-itemtype');
});
ApiClient.updateServerConfiguration(config);
});
// Disable default form submission
return false;
}
};
$(document).on('pageshow', "#advancedMetadataConfigurationPage", AdvancedMetadataConfigurationPage.onPageShow);

View file

@ -0,0 +1,462 @@
var DashboardPage = {
onPageShow: function () {
Dashboard.showLoadingMsg();
DashboardPage.pollForInfo();
DashboardPage.startInterval();
$(ApiClient).on("websocketmessage", DashboardPage.onWebSocketMessage).on("websocketopen", DashboardPage.onWebSocketConnectionChange).on("websocketerror", DashboardPage.onWebSocketConnectionChange).on("websocketclose", DashboardPage.onWebSocketConnectionChange);
DashboardPage.lastAppUpdateCheck = null;
DashboardPage.lastPluginUpdateCheck = null;
},
onPageHide: function () {
$(ApiClient).off("websocketmessage", DashboardPage.onWebSocketMessage).off("websocketopen", DashboardPage.onWebSocketConnectionChange).off("websocketerror", DashboardPage.onWebSocketConnectionChange).off("websocketclose", DashboardPage.onWebSocketConnectionChange);
DashboardPage.stopInterval();
},
startInterval: function () {
if (ApiClient.isWebSocketOpen()) {
ApiClient.sendWebSocketMessage("DashboardInfoStart", "0,1500");
}
},
stopInterval: function () {
if (ApiClient.isWebSocketOpen()) {
ApiClient.sendWebSocketMessage("DashboardInfoStop");
}
},
onWebSocketMessage: function (e, msg) {
if (msg.MessageType == "DashboardInfo") {
DashboardPage.renderInfo(msg.Data);
}
},
onWebSocketConnectionChange: function () {
DashboardPage.stopInterval();
DashboardPage.startInterval();
},
pollForInfo: function () {
$.getJSON("dashboardInfo").done(DashboardPage.renderInfo);
},
renderInfo: function (dashboardInfo) {
DashboardPage.lastDashboardInfo = dashboardInfo;
DashboardPage.renderRunningTasks(dashboardInfo);
DashboardPage.renderSystemInfo(dashboardInfo);
DashboardPage.renderActiveConnections(dashboardInfo);
Dashboard.hideLoadingMsg();
},
renderActiveConnections: function (dashboardInfo) {
var page = $.mobile.activePage;
var html = '';
if (!dashboardInfo.ActiveConnections.length) {
html += '<p>There are no users currently connected.</p>';
$('#divConnections', page).html(html).trigger('create');
return;
}
html += '<table class="tblConnections" style="border-collapse:collapse;">';
for (var i = 0, length = dashboardInfo.ActiveConnections.length; i < length; i++) {
var connection = dashboardInfo.ActiveConnections[i];
var user = dashboardInfo.Users.filter(function (u) {
return u.Id == connection.UserId;
})[0];
html += '<tr>';
html += '<td style="text-align:center;">';
html += DashboardPage.getClientType(connection);
html += '</td>';
html += '<td>';
html += user.Name;
html += '</td>';
html += '<td>';
html += connection.DeviceName;
html += '</td>';
html += '<td>';
html += DashboardPage.getNowPlayingImage(connection.NowPlayingItem);
html += '</td>';
html += '<td>';
html += DashboardPage.getNowPlayingText(connection, connection.NowPlayingItem);
html += '</td>';
html += '</tr>';
}
html += '</table>';
$('#divConnections', page).html(html);
},
getClientType: function (connection) {
var clientLowered = connection.Client.toLowerCase();
if (clientLowered == "dashboard") {
return "<img src='css/images/clients/html5.png' alt='Dashboard' title='Dashboard' />";
}
if (clientLowered == "media browser classic") {
return "<img src='css/images/clients/mb.png' alt='Media Browser Classic' title='Media Browser Classic' />";
}
if (clientLowered == "media browser theater") {
return "<img src='css/images/clients/mb.png' alt='Media Browser Theater' title='Media Browser Theater' />";
}
if (clientLowered == "android") {
return "<img src='css/images/clients/android.png' alt='Android' title='Android' />";
}
if (clientLowered == "ios") {
return "<img src='css/images/clients/ios.png' alt='iOS' title='iOS' />";
}
if (clientLowered == "windows rt") {
return "<img src='css/images/clients/windowsrt.png' alt='Windows RT' title='Windows RT' />";
}
if (clientLowered == "windows phone") {
return "<img src='css/images/clients/windowsphone.png' alt='Windows Phone' title='Windows Phone' />";
}
if (clientLowered == "dlna") {
return "<img src='css/images/clients/dlna.png' alt='Dlna' title='Dlna' />";
}
return connection.Client;
},
getNowPlayingImage: function (item) {
if (item) {
if (item.BackdropImageTag) {
var url = ApiClient.getImageUrl(item.Id, {
type: "Backdrop",
height: 100,
tag: item.BackdropImageTag
});
return "<img class='clientNowPlayingImage' src='" + url + "' alt='" + item.Name + "' title='" + item.Name + "' />";
}
else if (item.PrimaryImageTag) {
var url = ApiClient.getImageUrl(item.Id, {
type: "Primary",
height: 100,
tag: item.PrimaryImageTag
});
return "<img class='clientNowPlayingImage' src='" + url + "' alt='" + item.Name + "' title='" + item.Name + "' />";
}
}
return "";
},
getNowPlayingText: function (connection, item) {
var html = "";
if (item) {
html += "<div>" + item.Name + "</div>";
html += "<div>";
if (item.RunTimeTicks) {
html += DashboardPage.getDisplayText(connection.NowPlayingPositionTicks || 0) + " / ";
html += DashboardPage.getDisplayText(item.RunTimeTicks);
}
html += "</div>";
}
return html;
},
getDisplayText: function (ticks) {
var ticksPerHour = 36000000000;
var parts = [];
var hours = ticks / ticksPerHour;
hours = parseInt(hours);
if (hours) {
parts.push(hours);
}
ticks -= (hours * ticksPerHour);
var ticksPerMinute = 600000000;
var minutes = ticks / ticksPerMinute;
minutes = parseInt(minutes);
ticks -= (minutes * ticksPerMinute);
if (minutes < 10) {
minutes = '0' + minutes;
}
parts.push(minutes);
var ticksPerSecond = 10000000;
var seconds = ticks / ticksPerSecond;
seconds = parseInt(seconds);
if (seconds < 10) {
seconds = '0' + seconds;
}
parts.push(seconds);
return parts.join(':');
},
renderRunningTasks: function (dashboardInfo) {
var page = $.mobile.activePage;
var html = '';
if (!dashboardInfo.RunningTasks.length) {
html += '<p>No tasks are currently running.</p>';
}
for (var i = 0, length = dashboardInfo.RunningTasks.length; i < length; i++) {
var task = dashboardInfo.RunningTasks[i];
html += '<p>';
html += task.Name;
if (task.State == "Running") {
var progress = Math.round(task.CurrentProgressPercentage || 0);
html += '<span style="color:#267F00;margin-right:5px;font-weight:bold;"> - ' + progress + '%</span>';
html += '<button type="button" data-icon="stop" data-iconpos="notext" data-inline="true" data-theme="b" data-mini="true" onclick="DashboardPage.stopTask(\'' + task.Id + '\');">Stop</button>';
}
else if (task.State == "Cancelling") {
html += '<span style="color:#cc0000;"> - Stopping</span>';
}
html += '</p>';
}
$('#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);
DashboardPage.renderPendingInstallations(dashboardInfo.SystemInfo);
},
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[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: '<img src="css/images/notifications/error.png" class="notificationIcon" />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();
}
},
renderPendingInstallations: function (systemInfo) {
var page = $.mobile.activePage;
if (systemInfo.CompletedInstallations.length) {
$('#collapsiblePendingInstallations', page).show();
} else {
$('#collapsiblePendingInstallations', page).hide();
return;
}
var html = '';
for (var i = 0, length = systemInfo.CompletedInstallations.length; i < length; i++) {
var update = systemInfo.CompletedInstallations[i];
html += '<div><strong>' + update.Name + '</strong> (' + update.Version + ')</div>';
}
$('#pendingInstallations', page).html(html);
},
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) {
var elem = $('#pPluginUpdates', page);
if (updates.length) {
elem.show();
} else {
elem.hide();
return;
}
var html = '';
for (var i = 0, length = updates.length; i < length; i++) {
var update = updates[i];
html += '<p><strong>A new version of ' + update.name + ' is available!</strong></p>';
html += '<button type="button" data-icon="download" data-theme="b" onclick="DashboardPage.installPluginUpdate(this);" data-name="' + update.name + '" data-version="' + update.versionStr + '" data-classification="' + update.classification + '">Update Now</button>';
}
elem.html(html).trigger('create');
}).fail(function () {
Dashboard.showFooterNotification({ html: '<img src="css/images/notifications/error.png" class="notificationIcon" />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);

View file

@ -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);

View file

@ -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 += "<option value=''>None</option>";
for (var i = 0, length = allCultures.length; i < length; i++) {
var culture = allCultures[i];
html += "<option value='" + culture.ThreeLetterISOLanguageName + "'>" + culture.DisplayName + "</option>";
}
select.html(html).selectmenu("refresh");
},
populateRatings: function (allParentalRatings, page) {
var html = "";
html += "<option value=''>None</option>";
for (var i = 0, length = allParentalRatings.length; i < length; i++) {
var rating = allParentalRatings[i];
html += "<option value='" + rating.Value + "'>" + rating.Name + "</option>";
}
$('#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);

View file

@ -0,0 +1,331 @@
// 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 <organization> nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(function ($, window, undefined) {
// Given a query string, convert all the name/value pairs
// into a property/value object. If a name appears more than
// once in a query string, the value is automatically turned
// into an array.
function queryStringToObject(qstr) {
var result = {}, nvPairs = ((qstr || "").replace(/^\?/, "").split(/&/)), i, pair, n, v;
for (i = 0; i < nvPairs.length; i++) {
var pstr = nvPairs[i];
if (pstr) {
pair = pstr.split(/=/);
n = pair[0];
v = pair[1];
if (result[n] === undefined) {
result[n] = v;
} else {
if (typeof result[n] !== "object") {
result[n] = [result[n]];
}
result[n].push(v);
}
}
}
return result;
}
// The idea here is to listen for any pagebeforechange notifications from
// jQuery Mobile, and then muck with the toPage and options so that query
// params can be passed to embedded/internal pages. So for example, if a
// changePage() request for a URL like:
//
// http://mycompany.com/myapp/#page-1?foo=1&bar=2
//
// is made, the page that will actually get shown is:
//
// http://mycompany.com/myapp/#page-1
//
// The browser's location will still be updated to show the original URL.
// The query params for the embedded page are also added as a property/value
// object on the options object. You can access it from your page notifications
// via data.options.pageData.
$(document).bind("pagebeforechange", function (e, data) {
// We only want to handle the case where we are being asked
// to go to a page by URL, and only if that URL is referring
// to an internal page by id.
if (typeof data.toPage === "string") {
var u = $.mobile.path.parseUrl(data.toPage);
if ($.mobile.path.isEmbeddedPage(u)) {
// The request is for an internal page, if the hash
// contains query (search) params, strip them off the
// toPage URL and then set options.dataUrl appropriately
// so the location.hash shows the originally requested URL
// that hash the query params in the hash.
var u2 = $.mobile.path.parseUrl(u.hash.replace(/^#/, ""));
if (u2.search) {
if (!data.options.dataUrl) {
data.options.dataUrl = data.toPage;
}
data.options.pageData = queryStringToObject(u2.search);
data.toPage = u.hrefNoHash + "#" + u2.pathname;
}
}
}
});
})(jQuery, window);

View file

@ -0,0 +1,106 @@
var IndexPage = {
onPageShow: function () {
IndexPage.loadLibrary(Dashboard.getCurrentUserId(), this);
},
loadLibrary: function (userId, page) {
if (!userId) {
return;
}
page = $(page);
var options = {
limit: 5,
sortBy: "DateCreated",
sortOrder: "Descending",
filters: "IsRecentlyAdded,IsNotFolder",
ImageTypes: "Primary,Backdrop,Thumb",
recursive: true
};
ApiClient.getItems(userId, options).done(function (result) {
$('#divWhatsNew', page).html(Dashboard.getPosterViewHtml({
items: result.Items,
preferBackdrop: true,
showTitle: true
}));
});
options = {
limit: 5,
sortBy: "DatePlayed",
sortOrder: "Descending",
filters: "IsResumable",
recursive: true
};
ApiClient.getItems(userId, options).done(function (result) {
$('#divResumableItems', page).html(Dashboard.getPosterViewHtml({
items: result.Items,
preferBackdrop: true,
showTitle: true
}));
if (result.Items.length) {
$('#divResumable', page).show();
} else {
$('#divResumable', page).hide();
}
});
options = {
sortBy: "SortName"
};
ApiClient.getItems(userId, options).done(function (result) {
$('#divCollections', page).html(Dashboard.getPosterViewHtml({
items: result.Items,
showTitle: true
}));
});
IndexPage.loadMyLibrary(userId, page);
},
loadMyLibrary: function (userId, page) {
var items = [{
Name: "Recently Played",
IsFolder: true
}, {
Name: "Favorites",
IsFolder: true
}, {
Name: "Genres",
IsFolder: true
}, {
Name: "Studios",
IsFolder: true
}, {
Name: "Performers",
IsFolder: true
}, {
Name: "Directors",
IsFolder: true
}];
$('#divMyLibrary', page).html(Dashboard.getPosterViewHtml({
items: items,
showTitle: true
}));
}
};
$(document).on('pageshow', "#indexPage", IndexPage.onPageShow);

View file

@ -0,0 +1,376 @@
var ItemDetailPage = {
onPageShow: function () {
ItemDetailPage.reload();
$('#galleryCollapsible', this).on('expand', ItemDetailPage.onGalleryExpand);
},
onPageHide: function () {
$('#galleryCollapsible', this).off('expand', ItemDetailPage.onGalleryExpand);
ItemDetailPage.item = null;
},
reload: function () {
var id = getParameterByName('id');
Dashboard.showLoadingMsg();
ApiClient.getItem(Dashboard.getCurrentUserId(), id).done(ItemDetailPage.renderItem);
},
renderItem: function (item) {
ItemDetailPage.item = item;
var page = $.mobile.activePage;
ItemDetailPage.item = item;
var name = item.Name;
if (item.IndexNumber != null) {
name = item.IndexNumber + " - " + name;
}
Dashboard.setPageTitle(name);
ItemDetailPage.renderImage(item);
ItemDetailPage.renderOverviewBlock(item);
ItemDetailPage.renderScenes(item);
ItemDetailPage.renderMediaInfo(item);
$('#itemName', page).html(name);
Dashboard.hideLoadingMsg();
},
renderImage: function (item) {
var page = $.mobile.activePage;
var imageTags = item.ImageTags || {};
var html = '';
var url;
var useBackgroundColor;
if (imageTags.Primary) {
url = ApiClient.getImageUrl(item.Id, {
type: "Primary",
width: 800,
tag: item.ImageTags.Primary
});
}
else if (item.BackdropImageTags && item.BackdropImageTags.length) {
url = ApiClient.getImageUrl(item.Id, {
type: "Backdrop",
width: 800,
tag: item.BackdropImageTags[0]
});
}
else if (imageTags.Thumb) {
url = ApiClient.getImageUrl(item.Id, {
type: "Thumb",
width: 800,
tag: item.ImageTags.Thumb
});
}
else if (imageTags.Disc) {
url = ApiClient.getImageUrl(item.Id, {
type: "Disc",
width: 800,
tag: item.ImageTags.Disc
});
}
else if (item.MediaType == "Audio") {
url = "css/images/itemDetails/audioDefault.png";
useBackgroundColor = true;
}
else if (item.MediaType == "Game") {
url = "css/images/itemDetails/gameDefault.png";
useBackgroundColor = true;
}
else {
url = "css/images/itemDetails/videoDefault.png";
useBackgroundColor = true;
}
if (url) {
var style = useBackgroundColor ? "background-color:" + Dashboard.getRandomMetroColor() + ";" : "";
html += "<img class='itemDetailImage' src='" + url + "' style='" + style + "' />";
}
$('#itemImage', page).html(html);
},
renderOverviewBlock: function (item) {
var page = $.mobile.activePage;
if (item.Taglines && item.Taglines.length) {
$('#itemTagline', page).html(item.Taglines[0]).show();
} else {
$('#itemTagline', page).hide();
}
if (item.Overview) {
$('#itemOverview', page).html(item.Overview).show();
} else {
$('#itemOverview', page).hide();
}
if (item.CommunityRating) {
$('#itemCommunityRating', page).html(ItemDetailPage.getStarRating(item)).show().attr('title', item.CommunityRating);
} else {
$('#itemCommunityRating', page).hide();
}
if (MediaPlayer.canPlay(item)) {
$('#btnPlay', page).show();
$('#playButtonShadow', page).show();
} else {
$('#btnPlay', page).hide();
$('#playButtonShadow', page).hide();
}
var miscInfo = [];
if (item.ProductionYear) {
miscInfo.push(item.ProductionYear);
}
if (item.OfficialRating) {
miscInfo.push(item.OfficialRating);
}
if (item.RunTimeTicks) {
var minutes = item.RunTimeTicks / 600000000;
minutes = minutes || 1;
miscInfo.push(parseInt(minutes) + "min");
}
if (item.DisplayMediaType) {
miscInfo.push(item.DisplayMediaType);
}
if (item.VideoFormat && item.VideoFormat !== 'Standard') {
miscInfo.push(item.VideoFormat);
}
$('#itemMiscInfo', page).html(miscInfo.join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'));
ItemDetailPage.renderGenres(item);
ItemDetailPage.renderStudios(item);
},
renderGenres: function (item) {
var page = $.mobile.activePage;
if (item.Genres && item.Genres.length) {
var elem = $('#itemGenres', page).show();
var html = 'Genres:&nbsp;&nbsp;';
for (var i = 0, length = item.Genres.length; i < length; i++) {
if (i > 0) {
html += '&nbsp;&nbsp;/&nbsp;&nbsp;';
}
html += '<a class="interiorLink" href="#">' + item.Genres[i] + '</a>';
}
elem.html(html);
} else {
$('#itemGenres', page).hide();
}
},
renderStudios: function (item) {
var page = $.mobile.activePage;
if (item.Studios && item.Studios.length) {
var elem = $('#itemStudios', page).show();
var html = 'Studios:&nbsp;&nbsp;';
for (var i = 0, length = item.Studios.length; i < length; i++) {
if (i > 0) {
html += '&nbsp;&nbsp;/&nbsp;&nbsp;';
}
html += '<a class="interiorLink" href="#">' + item.Studios[i] + '</a>';
}
elem.html(html);
} else {
$('#itemStudios', page).hide();
}
},
getStarRating: function (item) {
var rating = item.CommunityRating;
var html = "";
for (var i = 1; i <= 10; i++) {
if (rating < i - 1) {
html += "<div class='starRating emptyStarRating'></div>";
}
else if (rating < i) {
html += "<div class='starRating halfStarRating'></div>";
}
else {
html += "<div class='starRating'></div>";
}
}
return html;
},
renderScenes: function (item) {
var html = '';
var page = $.mobile.activePage;
if (!item.Chapters || !item.Chapters.length) {
$('#scenesCollapsible', page).hide();
$('#scenesContent', page).html(html);
return;
}
for (var i = 0, length = item.Chapters.length; i < length; i++) {
var chapter = item.Chapters[i];
}
$('#scenesCollapsible', page).show();
$('#scenesContent', page).html(html);
},
play: function () {
MediaPlayer.play([ItemDetailPage.item]);
},
onGalleryExpand: function() {
if (ItemDetailPage.item) {
ItemDetailPage.renderGallery(ItemDetailPage.item);
$(this).off('expand', ItemDetailPage.onGalleryExpand);
}
},
renderGallery: function (item) {
var page = $.mobile.activePage;
var imageTags = item.ImageTags || {};
var html = '';
var downloadWidth = 400;
if (imageTags.Logo) {
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
type: "Logo",
width: downloadWidth,
tag: item.ImageTags.Logo
}) + '" />';
}
if (imageTags.Thumb) {
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
type: "Thumb",
width: downloadWidth,
tag: item.ImageTags.Thumb
}) + '" />';
}
if (imageTags.Art) {
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
type: "Art",
width: downloadWidth,
tag: item.ImageTags.Art
}) + '" />';
}
if (imageTags.Menu) {
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
type: "Menu",
width: downloadWidth,
tag: item.ImageTags.Menu
}) + '" />';
}
if (imageTags.Disc) {
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
type: "Disc",
width: downloadWidth,
tag: item.ImageTags.Disc
}) + '" />';
}
if (imageTags.Box) {
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
type: "Box",
width: downloadWidth,
tag: item.ImageTags.Box
}) + '" />';
}
if (item.BackdropImageTags) {
for (var i = 0, length = item.BackdropImageTags.length; i < length; i++) {
html += '<img class="galleryImage" src="' + ApiClient.getImageUrl(item.Id, {
type: "Backdrop",
width: downloadWidth,
tag: item.BackdropImageTags[0],
index: i
}) + '" />';
}
}
$('#galleryContent', page).html(html);
},
renderMediaInfo: function(item) {
var page = $.mobile.activePage;
if (!item.MediaStreams || !item.MediaStreams.length) {
$('#mediaInfoCollapsible', page).hide();
return;
}
$('#mediaInfoCollapsible', page).show();
}
};
$(document).on('pageshow', "#itemDetailPage", ItemDetailPage.onPageShow).on('pagehide', "#itemDetailPage", ItemDetailPage.onPageHide);

View file

@ -0,0 +1,46 @@
var ItemListPage = {
onPageShow: function () {
ItemListPage.reload();
},
reload: function () {
var userId = Dashboard.getCurrentUserId();
var parentId = getParameterByName('parentId');
var query = {};
if (parentId) {
query.parentId = parentId;
ApiClient.getItem(userId, parentId).done(ItemListPage.renderTitle);
}
ApiClient.getItems(userId, query).done(ItemListPage.renderItems);
},
renderItems: function(result) {
var items = result.Items;
var renderOptions = {
items: items
};
var html = Dashboard.getPosterViewHtml(renderOptions);
$('#listItems', $.mobile.activePage).html(html);
},
renderTitle: function (item) {
$('#itemName', $.mobile.activePage).html(item.Name);
}
};
$(document).on('pageshow', "#itemListPage", ItemListPage.onPageShow);

View file

@ -0,0 +1,86 @@
var LogPage = {
onPageShow: function () {
LogPage.startLine = 0;
$('#logContents', this).html('');
$(ApiClient).on("websocketmessage", LogPage.onWebSocketMessage).on("websocketopen", LogPage.onWebSocketConnectionChange).on("websocketerror", LogPage.onWebSocketConnectionChange).on("websocketclose", LogPage.onWebSocketConnectionChange);
LogPage.startInterval();
var autoScroll = localStorage.getItem("autoScrollLogPage");
if (autoScroll == "true") {
LogPage.updateAutoScroll(true);
}
else if (autoScroll == "false") {
LogPage.updateAutoScroll(false);
}
},
onPageHide: function () {
$(ApiClient).off("websocketmessage", LogPage.onWebSocketMessage).off("websocketopen", LogPage.onWebSocketConnectionChange).off("websocketerror", LogPage.onWebSocketConnectionChange).off("websocketclose", LogPage.onWebSocketConnectionChange);
LogPage.stopInterval();
},
startInterval: function () {
if (ApiClient.isWebSocketOpen()) {
ApiClient.sendWebSocketMessage("LogFileStart", "0,2000");
}
},
stopInterval: function () {
if (ApiClient.isWebSocketOpen()) {
ApiClient.sendWebSocketMessage("LogFileStop");
}
},
onWebSocketConnectionChange: function () {
LogPage.stopInterval();
LogPage.startInterval();
},
onWebSocketMessage: function (e, msg) {
if (msg.MessageType == "LogFile") {
LogPage.appendLines(msg.Data);
}
},
appendLines: function (lines) {
if (!lines.length) {
return;
}
LogPage.startLine += lines.length;
lines = lines.join('\n') + '\n';
var elem = $('#logContents', $.mobile.activePage).append(lines)[0];
elem.style.height = (elem.scrollHeight) + 'px';
if ($('#chkAutoScroll', $.mobile.activePage).checked()) {
$('html, body').animate({ scrollTop: $(document).height() }, 'slow');
}
},
updateAutoScroll: function (value) {
var page = $.mobile.activePage;
$('#chkAutoScrollBottom', page).checked(value).checkboxradio('refresh');
$('#chkAutoScroll', page).checked(value).checkboxradio('refresh');
localStorage.setItem("autoScrollLogPage", value.toString());
}
};
$(document).on('pageshow', "#logPage", LogPage.onPageShow).on('pagehide', "#logPage", LogPage.onPageHide);

View file

@ -0,0 +1,119 @@
var LoginPage = {
onPageShow: function () {
Dashboard.showLoadingMsg();
ApiClient.getUsers().done(LoginPage.loadUserList);
},
getLastSeenText: function (lastActivityDate) {
if (!lastActivityDate) {
return "";
}
return "Last seen " + humane_date(lastActivityDate);
},
getImagePath: function (user) {
if (!user.PrimaryImageTag) {
return "css/images/logindefault.png";
}
return ApiClient.getUserImageUrl(user.Id, {
width: 240,
tag: user.PrimaryImageTag,
type: "Primary"
});
},
authenticateUserLink: function (link) {
LoginPage.authenticateUser(link.getAttribute('data-username'), link.getAttribute('data-userid'));
},
authenticateUser: function (username, userId, password) {
Dashboard.showLoadingMsg();
ApiClient.authenticateUser(userId, password).done(function () {
Dashboard.setCurrentUser(userId);
window.location = "index.html?u=" + userId;
}).fail(function () {
Dashboard.hideLoadingMsg();
setTimeout(function () {
Dashboard.showError("Invalid user or password.");
}, 300);
});
},
loadUserList: function (users) {
var html = "";
for (var i = 0, length = users.length; i < length; i++) {
var user = users[i];
var linkId = "lnkUser" + i;
var background = Dashboard.getRandomMetroColor();
html += '<div class="posterViewItem posterViewItemWithDualText">';
if (user.HasPassword) {
html += "<a id='" + linkId + "' data-userid='" + user.Id + "' data-username='" + user.Name + "' href='#popupLogin' data-rel='popup' onclick='LoginPage.authenticatingLinkId=this.id;' \">";
} else {
html += "<a id='" + linkId + "' data-userid='" + user.Id + "' data-username='" + user.Name + "' href='#' onclick='LoginPage.authenticateUserLink(this);' \">";
}
if (user.PrimaryImageTag) {
var imgUrl = ApiClient.getUserImageUrl(user.Id, {
width: 500,
tag: user.PrimaryImageTag,
type: "Primary"
});
html += '<img src="' + imgUrl + '" />';
} else {
html += '<img style="background:' + background + ';" src="css/images/logindefault.png"/>';
}
html += '<div class="posterViewItemText posterViewItemPrimaryText">' + user.Name + '</div>';
html += '<div class="posterViewItemText">';
var lastSeen = LoginPage.getLastSeenText(user.LastActivityDate);
if (lastSeen != "") {
html += lastSeen;
}
else {
html += "&nbsp;";
}
html += '</div>';
html += '</a>';
html += '</div>';
}
$('#divUsers', '#loginPage').html(html);
Dashboard.hideLoadingMsg();
},
onSubmit: function () {
$('#popupLogin', '#loginPage').popup('close');
var link = $('#' + LoginPage.authenticatingLinkId)[0];
LoginPage.authenticateUser(link.getAttribute('data-username'), link.getAttribute('data-userid'), $('#pw', '#loginPage').val());
// Disable default form submission
return false;
}
};
$(document).on('pageshow', "#loginPage", LoginPage.onPageShow);

View file

@ -0,0 +1,272 @@
var MediaLibraryPage = {
onPageShow: function () {
MediaLibraryPage.lastVirtualFolderName = "";
MediaLibraryPage.reloadLibrary();
},
reloadLibrary: function () {
Dashboard.showLoadingMsg();
var userId = getParameterByName("userId");
var page = $.mobile.activePage;
if (userId) {
$('#userProfileNavigation', page).show();
ApiClient.getUser(userId).done(function (user) {
Dashboard.setPageTitle(user.Name);
$('#fldUseDefaultLibrary', page).show();
$('#chkUseDefaultLibrary', page).checked(!user.Configuration.UseCustomLibrary).checkboxradio("refresh");
if (user.Configuration.UseCustomLibrary) {
ApiClient.getVirtualFolders(userId).done(MediaLibraryPage.reloadVirtualFolders);
$('#divMediaLibrary', page).show();
} else {
$('#divMediaLibrary', page).hide();
Dashboard.hideLoadingMsg();
}
});
} else {
$('#userProfileNavigation', page).hide();
ApiClient.getVirtualFolders().done(MediaLibraryPage.reloadVirtualFolders);
$('#fldUseDefaultLibrary', page).hide();
$('#divMediaLibrary', page).show();
Dashboard.setPageTitle("Media Library");
}
},
reloadVirtualFolders: function (virtualFolders) {
var page = $.mobile.activePage;
if (virtualFolders) {
MediaLibraryPage.virtualFolders = virtualFolders;
} else {
virtualFolders = MediaLibraryPage.virtualFolders;
}
var html = '';
for (var i = 0, length = virtualFolders.length; i < length; i++) {
var virtualFolder = virtualFolders[i];
var isCollapsed = MediaLibraryPage.lastVirtualFolderName != virtualFolder.Name;
html += MediaLibraryPage.getVirtualFolderHtml(virtualFolder, isCollapsed, i);
}
$('#divVirtualFolders', page).html(html).trigger('create');
Dashboard.hideLoadingMsg();
},
getVirtualFolderHtml: function (virtualFolder, isCollapsed, index) {
isCollapsed = isCollapsed ? "true" : "false";
var html = '<div class="collapsibleVirtualFolder" data-role="collapsible" data-collapsed="' + isCollapsed + '" data-content-theme="c">';
html += '<h3>' + virtualFolder.Name + '</h3>';
html += '<ul class="mediaFolderLocations" data-inset="true" data-role="listview" data-split-icon="minus">';
html += '<li data-role="list-divider" class="mediaLocationsHeader">Media Locations';
html += '<button type="button" data-icon="plus" data-mini="true" data-theme="c" data-inline="true" data-iconpos="notext" onclick="MediaLibraryPage.addMediaLocation(' + index + ');"></button>';
html += '</li>';
for (var i = 0, length = virtualFolder.Locations.length; i < length; i++) {
var location = virtualFolder.Locations[i];
html += '<li>';
html += '<a class="lnkMediaLocation" href="#">' + location + '</a>';
html += '<a href="#" data-index="' + i + '" data-folderindex="' + index + '" onclick="MediaLibraryPage.deleteMediaLocation(this);"></a>';
html += '</li>';
}
html += '</ul>';
html += '<p>';
html += '<button type="button" data-inline="true" data-icon="minus" data-folderindex="' + index + '" onclick="MediaLibraryPage.deleteVirtualFolder(this);">Remove collection</button>';
html += '<button type="button" data-inline="true" data-icon="pencil" data-folderindex="' + index + '" onclick="MediaLibraryPage.renameVirtualFolder(this);">Rename collection</button>';
html += '</p>';
html += '</div>';
return html;
},
setUseDefaultMediaLibrary: function (useDefaultLibrary) {
Dashboard.showLoadingMsg();
var userId = getParameterByName("userId");
ApiClient.getUser(userId).done(function (user) {
user.Configuration.UseCustomLibrary = !useDefaultLibrary;
ApiClient.updateUser(user).done(MediaLibraryPage.reloadLibrary);
});
},
addVirtualFolder: function () {
MediaLibraryPage.getTextValue("Add Media Collection", "Name:", "", function (name) {
var userId = getParameterByName("userId");
MediaLibraryPage.lastVirtualFolderName = name;
ApiClient.addVirtualFolder(name, userId).done(MediaLibraryPage.processOperationResult);
});
},
addMediaLocation: function (virtualFolderIndex) {
MediaLibraryPage.selectDirectory(function (path) {
if (path) {
var virtualFolder = MediaLibraryPage.virtualFolders[virtualFolderIndex];
MediaLibraryPage.lastVirtualFolderName = virtualFolder.Name;
var userId = getParameterByName("userId");
ApiClient.addMediaPath(virtualFolder.Name, path, userId).done(MediaLibraryPage.processOperationResult);
}
});
},
selectDirectory: function (callback) {
Dashboard.selectDirectory({callback: callback});
},
getTextValue: function (header, label, initialValue, callback) {
var page = $.mobile.activePage;
var popup = $('#popupEnterText', page);
$('h3', popup).html(header);
$('label', popup).html(label);
$('#txtValue', popup).val(initialValue);
popup.popup("open").on("popupafterclose", function () {
$(this).off("popupafterclose").off("click");
$('#textEntryForm', this).off("submit");
});
$('#textEntryForm', popup).on('submit', function () {
if (callback) {
callback($('#txtValue', popup).val());
}
return false;
});
},
renameVirtualFolder: function (button) {
var folderIndex = button.getAttribute('data-folderindex');
var virtualFolder = MediaLibraryPage.virtualFolders[folderIndex];
MediaLibraryPage.lastVirtualFolderName = virtualFolder.Name;
MediaLibraryPage.getTextValue(virtualFolder.Name, "Rename " + virtualFolder.Name, virtualFolder.Name, function (newName) {
if (virtualFolder.Name != newName) {
var userId = getParameterByName("userId");
ApiClient.renameVirtualFolder(virtualFolder.Name, newName, userId).done(MediaLibraryPage.processOperationResult);
}
});
},
deleteVirtualFolder: function (button) {
var folderIndex = button.getAttribute('data-folderindex');
var virtualFolder = MediaLibraryPage.virtualFolders[folderIndex];
var parent = $(button).parents('.collapsibleVirtualFolder');
var locations = $('.lnkMediaLocation', parent).map(function () {
return this.innerHTML;
}).get();
var msg = "Are you sure you wish to remove " + virtualFolder.Name + "?";
if (locations.length) {
msg += "<br/><br/>The following media locations will be removed from your library:<br/><br/>";
msg += locations.join("<br/>");
}
MediaLibraryPage.lastVirtualFolderName = virtualFolder.Name;
Dashboard.confirm(msg, "Remove Media Folder", function (confirmResult) {
if (confirmResult) {
var userId = getParameterByName("userId");
ApiClient.removeVirtualFolder(virtualFolder.Name, userId).done(MediaLibraryPage.processOperationResult);
}
});
},
deleteMediaLocation: function (button) {
var folderIndex = button.getAttribute('data-folderindex');
var index = parseInt(button.getAttribute('data-index'));
var virtualFolder = MediaLibraryPage.virtualFolders[folderIndex];
MediaLibraryPage.lastVirtualFolderName = virtualFolder.Name;
var location = virtualFolder.Locations[index];
Dashboard.confirm("Are you sure you wish to remove " + location + "?", "Remove Media Location", function (confirmResult) {
if (confirmResult) {
var userId = getParameterByName("userId");
ApiClient.removeMediaPath(virtualFolder.Name, location, userId).done(MediaLibraryPage.processOperationResult);
}
});
},
processOperationResult: function (result) {
Dashboard.hideLoadingMsg();
var page = $.mobile.activePage;
$('#popupEnterText', page).popup("close");
$('#popupDirectoryPicker', page).popup("close");
MediaLibraryPage.reloadLibrary();
}
};
$(document).on('pageshow', ".mediaLibraryPage", MediaLibraryPage.onPageShow);

View file

@ -0,0 +1,185 @@
var MediaPlayer = {
testableAudioElement: document.createElement('audio'),
testableVideoElement: document.createElement('video'),
canPlay: function (item) {
if (item.MediaType === "Video") {
var media = MediaPlayer.testableVideoElement;
if (media.canPlayType) {
return media.canPlayType('video/mp4').replace(/no/, '') || media.canPlayType('video/mp2t').replace(/no/, '') || media.canPlayType('video/webm').replace(/no/, '') || media.canPlayType('application/x-mpegURL').replace(/no/, '') || media.canPlayType('video/ogv').replace(/no/, '');
}
return false;
}
if (item.MediaType === "Audio") {
var media = MediaPlayer.testableAudioElement;
if (media.canPlayType) {
return media.canPlayType('audio/mpeg').replace(/no/, '') || media.canPlayType('audio/aac').replace(/no/, '');
}
return false;
}
return false;
},
play: function (items) {
if (MediaPlayer.isPlaying()) {
MediaPlayer.stop();
}
var item = items[0];
var mediaElement;
if (item.MediaType === "Video") {
mediaElement = MediaPlayer.playVideo(items);
}
else if (item.MediaType === "Audio") {
mediaElement = MediaPlayer.playAudio(items);
}
if (!mediaElement) {
return;
}
MediaPlayer.mediaElement = mediaElement;
var nowPlayingBar = $('#nowPlayingBar').show();
if (items.length > 1) {
$('#previousTrackButton', nowPlayingBar)[0].disabled = false;
$('#nextTrackButton', nowPlayingBar)[0].disabled = false;
} else {
$('#previousTrackButton', nowPlayingBar)[0].disabled = true;
$('#nextTrackButton', nowPlayingBar)[0].disabled = true;
}
},
playAudio: function (items) {
var item = items[0];
var baseParams = {
audioChannels: 2,
audioBitrate: 128000
};
var mp3Url = ApiClient.getUrl('Audio/' + item.Id + '/stream.mp3', $.extend({}, baseParams, {
audioCodec: 'mp3'
}));
var aacUrl = ApiClient.getUrl('Audio/' + item.Id + '/stream.aac', $.extend({}, baseParams, {
audioCodec: 'aac'
}));
var webmUrl = ApiClient.getUrl('Audio/' + item.Id + '/stream.webma', $.extend({}, baseParams, {
audioCodec: 'Vorbis'
}));
var oggUrl = ApiClient.getUrl('Audio/' + item.Id + '/stream.oga', $.extend({}, baseParams, {
audioCodec: 'Vorbis'
}));
var html = '';
html += '<audio class="itemAudio" preload="none" controls autoplay>';
html += '<source type="audio/mpeg" src="' + mp3Url + '" />';
html += '<source type="audio/aac" src="' + aacUrl + '" />';
html += '<source type="audio/webm" src="' + webmUrl + '" />';
html += '<source type="audio/ogg" src="' + oggUrl + '" />';
html += '</audio';
var nowPlayingBar = $('#nowPlayingBar').show();
$('#mediaElement', nowPlayingBar).html(html);
return $('audio', nowPlayingBar)[0];
},
playVideo: function (items) {
var item = items[0];
// Account for screen rotation. Use the larger dimension as the width.
var screenWidth = Math.max(screen.height, screen.width);
var screenHeight = Math.min(screen.height, screen.width);
var baseParams = {
audioChannels: 2,
audioBitrate: 128000,
videoBitrate: 500000,
maxWidth: screenWidth,
maxHeight: screenHeight
};
var mp4VideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.mp4', $.extend({}, baseParams, {
videoCodec: 'h264',
audioCodec: 'aac'
}));
var tsVideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.ts', $.extend({}, baseParams, {
videoCodec: 'h264',
audioCodec: 'aac'
}));
var webmVideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.webm', $.extend({}, baseParams, {
videoCodec: 'vpx',
audioCodec: 'Vorbis'
}));
var hlsVideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.m3u8', $.extend({}, baseParams, {
videoCodec: 'h264',
audioCodec: 'aac'
}));
var ogvVideoUrl = ApiClient.getUrl('Videos/' + item.Id + '/stream.ogv', $.extend({}, baseParams, {
videoCodec: 'theora',
audioCodec: 'Vorbis'
}));
var html = '';
html += '<video class="itemVideo" preload="none" controls autoplay>';
html += '<source type="video/webm" src="' + webmVideoUrl + '" />';
html += '<source type="video/mp4" src="' + mp4VideoUrl + '" />';
html += '<source type=\'video/mp2t; codecs="h264, aac"\' src="' + tsVideoUrl + '" />';
html += '<source type="application/x-mpegURL" src="' + hlsVideoUrl + '" />';
html += '<source type="video/ogg" src="' + ogvVideoUrl + '" />';
html += '</video';
var nowPlayingBar = $('#nowPlayingBar').show();
$('#mediaElement', nowPlayingBar).html(html);
return $('video', nowPlayingBar)[0];
},
stop: function () {
var elem = MediaPlayer.mediaElement;
elem.pause();
elem.src = "";
$(elem).remove();
$('#nowPlayingBar').hide();
MediaPlayer.mediaElement = null;
},
isPlaying: function () {
return MediaPlayer.mediaElement;
}
};

View file

@ -0,0 +1,107 @@
var MetadataConfigurationPage = {
onPageShow: function () {
Dashboard.showLoadingMsg();
var page = this;
var config;
var allCultures;
var allCountries;
ApiClient.getServerConfiguration().done(function (result) {
config = result;
MetadataConfigurationPage.load(page, config, allCultures, allCountries);
});
ApiClient.getCultures().done(function (result) {
MetadataConfigurationPage.populateLanguages(result);
allCultures = result;
MetadataConfigurationPage.load(page, config, allCultures, allCountries);
});
ApiClient.getCountries().done(function (result) {
MetadataConfigurationPage.populateCountries(result);
allCountries = result;
MetadataConfigurationPage.load(page, config, allCultures, allCountries);
});
},
load: function (page, config, allCultures, allCountries) {
if (!config || !allCultures || !allCountries) {
return;
}
$('#chkEnableInternetProviders', page).checked(config.EnableInternetProviders).checkboxradio("refresh");
$('#chkSaveLocal', page).checked(config.SaveLocalMeta).checkboxradio("refresh");
$('#txtRefreshDays', page).val(config.MetadataRefreshDays);
$('#selectLanguage', page).val(config.PreferredMetadataLanguage).selectmenu("refresh");
$('#selectCountry', page).val(config.MetadataCountryCode).selectmenu("refresh");
Dashboard.hideLoadingMsg();
},
populateCountries: function (allCountries) {
var html = "";
html += "<option value=''>None</option>";
for (var i = 0, length = allCountries.length; i < length; i++) {
var culture = allCountries[i];
html += "<option value='" + culture.TwoLetterISORegionName + "'>" + culture.DisplayName + "</option>";
}
$('#selectCountry', '#metadataConfigurationPage').html(html).selectmenu("refresh");
},
populateLanguages: function (allCultures) {
var html = "";
html += "<option value=''>None</option>";
for (var i = 0, length = allCultures.length; i < length; i++) {
var culture = allCultures[i];
html += "<option value='" + culture.TwoLetterISOLanguageName + "'>" + culture.DisplayName + "</option>";
}
$('#selectLanguage', '#metadataConfigurationPage').html(html).selectmenu("refresh");
},
submit: function () {
$('.btnSubmit', $.mobile.activePage)[0].click();
},
onSubmit: function () {
var form = this;
ApiClient.getServerConfiguration().done(function (config) {
config.EnableInternetProviders = $('#chkEnableInternetProviders', form).checked();
config.SaveLocalMeta = $('#chkSaveLocal', form).checked();
config.MetadataRefreshDays = $('#txtRefreshDays', form).val();
config.PreferredMetadataLanguage = $('#selectLanguage', form).val();
config.MetadataCountryCode = $('#selectCountry', form).val();
ApiClient.updateServerConfiguration(config);
});
// Disable default form submission
return false;
}
};
$(document).on('pageshow', "#metadataConfigurationPage", MetadataConfigurationPage.onPageShow);

View file

@ -0,0 +1,90 @@
var MetadataImagesPage = {
onPageShow: function () {
Dashboard.showLoadingMsg();
var page = this;
ApiClient.getServerConfiguration().done(function(result) {
MetadataImagesPage.load(page, result);
});
},
load: function (page, config) {
$('#selectTmdbPersonImageDownloadSize', page).val(config.TmdbFetchedProfileSize).selectmenu("refresh");
$('#selectTmdbPosterDownloadSize', page).val(config.TmdbFetchedPosterSize).selectmenu("refresh");
$('#selectTmdbBackdropDownloadSize', page).val(config.TmdbFetchedBackdropSize).selectmenu("refresh");
$('#chkRefreshItemImages', page).checked(config.RefreshItemImages).checkboxradio("refresh");
$('#txtNumbackdrops', page).val(config.MaxBackdrops);
$('#chkDownloadMovieArt', page).checked(config.DownloadMovieImages.Art).checkboxradio("refresh");
$('#chkDownloadMovieBanner', page).checked(config.DownloadMovieImages.Banner).checkboxradio("refresh");
$('#chkDownloadMovieDisc', page).checked(config.DownloadMovieImages.Disc).checkboxradio("refresh");
$('#chkDownloadMovieLogo', page).checked(config.DownloadMovieImages.Logo).checkboxradio("refresh");
$('#chkDownloadMovieThumb', page).checked(config.DownloadMovieImages.Thumb).checkboxradio("refresh");
$('#chKDownloadTVArt', page).checked(config.DownloadSeriesImages.Art).checkboxradio("refresh");
$('#chkDownloadTVBanner', page).checked(config.DownloadSeriesImages.Banner).checkboxradio("refresh");
$('#chkDownloadTVLogo', page).checked(config.DownloadSeriesImages.Logo).checkboxradio("refresh");
$('#chkDownloadTVThumb', page).checked(config.DownloadSeriesImages.Thumb).checkboxradio("refresh");
$('#chkDownloadSeasonBanner', page).checked(config.DownloadSeasonImages.Banner).checkboxradio("refresh");
$('#chkDownloadSeasonThumb', page).checked(config.DownloadSeasonImages.Thumb).checkboxradio("refresh");
$('#chkDownloadSeasonBackdrops', page).checked(config.DownloadSeasonImages.Backdrops).checkboxradio("refresh");
$('#chkDownloadArtistThumb', page).checked(config.DownloadMusicArtistImages.Thumb).checkboxradio("refresh");
$('#chkDownloadArtistBackdrops', page).checked(config.DownloadMusicArtistImages.Backdrops).checkboxradio("refresh");
$('#chkDownloadArtistLogo', page).checked(config.DownloadMusicArtistImages.Logo).checkboxradio("refresh");
$('#chkDownloadArtistBanner', page).checked(config.DownloadMusicArtistImages.Banner).checkboxradio("refresh");
$('#chkDownloadAlbumPrimary', page).checked(config.DownloadMusicAlbumImages.Primary).checkboxradio("refresh");
$('#chkDownloadAlbumBackdrops', page).checked(config.DownloadMusicAlbumImages.Backdrops).checkboxradio("refresh");
Dashboard.hideLoadingMsg();
},
submit: function () {
$('.btnSubmit', $.mobile.activePage)[0].click();
},
onSubmit: function () {
var form = this;
ApiClient.getServerConfiguration().done(function (config) {
config.TmdbFetchedProfileSize = $('#selectTmdbPersonImageDownloadSize', form).val();
config.TmdbFetchedPosterSize = $('#selectTmdbPosterDownloadSize', form).val();
config.TmdbFetchedBackdropSize = $('#selectTmdbBackdropDownloadSize', form).val();
config.RefreshItemImages = $('#chkRefreshItemImages', form).checked();
config.MaxBackdrops = $('#txtNumbackdrops', form).val();
config.DownloadMovieImages.Art = $('#chkDownloadMovieArt', form).checked();
config.DownloadMovieImages.Banner = $('#chkDownloadMovieBanner', form).checked();
config.DownloadMovieImages.Disc = $('#chkDownloadMovieDisc', form).checked();
config.DownloadMovieImages.Logo = $('#chkDownloadMovieLogo', form).checked();
config.DownloadMovieImages.Thumb = $('#chkDownloadMovieThumb', form).checked();
config.DownloadSeriesImages.Art = $('#chKDownloadTVArt', form).checked();
config.DownloadSeriesImages.Banner = $('#chkDownloadTVBanner', form).checked();
config.DownloadSeriesImages.Logo = $('#chkDownloadTVLogo', form).checked();
config.DownloadSeriesImages.Thumb = $('#chkDownloadTVThumb', form).checked();
config.DownloadSeasonImages.Banner = $('#chkDownloadSeasonBanner', form).checked();
config.DownloadSeasonImages.Thumb = $('#chkDownloadSeasonThumb', form).checked();
config.DownloadSeasonImages.Backdrops = $('#chkDownloadSeasonBackdrops', form).checked();
config.DownloadMusicArtistImages.Backdrops = $('#chkDownloadArtistBackdrops', form).checked();
config.DownloadMusicArtistImages.Logo = $('#chkDownloadArtistLogo', form).checked();
config.DownloadMusicArtistImages.Thumb = $('#chkDownloadArtistThumb', form).checked();
config.DownloadMusicArtistImages.Banner = $('#chkDownloadArtistBanner', form).checked();
config.DownloadMusicAlbumImages.Primary = $('#chkDownloadAlbumPrimary', form).checked();
config.DownloadMusicAlbumImages.Backdrops = $('#chkDownloadAlbumBackdrops', form).checked();
ApiClient.updateServerConfiguration(config);
});
// Disable default form submission
return false;
}
};
$(document).on('pageshow', "#metadataImagesConfigurationPage", MetadataImagesPage.onPageShow);

View file

@ -0,0 +1,86 @@
var PluginCatalogPage = {
onPageShow: function () {
PluginCatalogPage.reloadList();
},
reloadList: function () {
Dashboard.showLoadingMsg();
var promise1 = ApiClient.getAvailablePlugins();
var promise2 = ApiClient.getInstalledPlugins();
$.when(promise1, promise2).done(function (response1, response2) {
PluginCatalogPage.populateList(response1[0], response2[0]);
});
},
populateList: function (availablePlugins, installedPlugins) {
var page = $($.mobile.activePage);
availablePlugins = availablePlugins.filter(function (p) {
return p.type == "UserInstalled";
}).sort(function (a, b) {
return a.name > b.name ? 1 : -1;
});
var html = "";
for (var i = 0, length = availablePlugins.length; i < length; i++) {
var plugin = availablePlugins[i];
html += "<div class='posterViewItem'><a href='addPlugin.html?name=" + encodeURIComponent(plugin.name) + "'>";
if (plugin.thumbImage) {
html += "<img src='" + plugin.thumbImage + "' />";
} else {
html += "<img style='background:#444444;' src='css/images/defaultCollectionImage.png' />";
}
if (plugin.isPremium) {
if (plugin.price > 0) {
html += "<div class='premiumBanner'><img src='css/images/premiumflag.png' /></div>";
} else {
html += "<div class='premiumBanner'><img src='css/images/supporterflag.png' /></div>";
}
}
var color = plugin.tileColor || Dashboard.getRandomMetroColor();
html += "<div class='posterViewItemText' style='background:" + color + "'>";
var installedPlugin = installedPlugins.filter(function (ip) {
return ip.Name == plugin.name;
})[0];
html += "<div>";
if (installedPlugin) {
html += plugin.name + " (Installed)";
} else {
html += plugin.name;
}
html += "</div>";
html += "</div>";
html += "</a></div>";
}
$('#pluginTiles', page).html(html);
Dashboard.hideLoadingMsg();
}
};
$(document).on('pageshow', "#pluginCatalogPage", PluginCatalogPage.onPageShow);

View file

@ -0,0 +1,104 @@
var PluginUpdatesPage = {
onPageShow: function () {
Dashboard.showLoadingMsg();
$('.liPluginUpdate', this).remove();
ApiClient.getInstalledPlugins().done(PluginUpdatesPage.loadPlugins);
},
loadPlugins: function (plugins) {
var elem = $('#tbodyPluginUpdates', $.mobile.activePage).html('');
for (var i = 0, length = plugins.length; i < length; i++) {
PluginUpdatesPage.addPlugin(plugins[i], i, elem);
}
Dashboard.hideLoadingMsg();
},
addPlugin: function (plugin, fieldIndex, elem) {
var html = "";
html += "<tr>";
html += "<td><h3>" + plugin.Name + "</h3></td>";
var fieldId = "liPluginUpdateFielda" + fieldIndex;
var options = PluginUpdatesPage.getHtmlOptions(["Off", "On"], (plugin.EnableAutoUpdate ? "On" : "Off"));
html += "<td>";
html += "<select data-id='" + plugin.Id + "' onchange='PluginUpdatesPage.setAutoUpdate(this);' data-role='slider' id='" + fieldId + "' name='" + fieldId + "'>" + options + "</select>";
html += "</td>";
fieldId = "liPluginUpdateFieldb" + fieldIndex;
options = PluginUpdatesPage.getHtmlOptions(["Release", "Beta", "Dev"], plugin.UpdateClass);
html += "<td>";
html += "<select data-id='" + plugin.Id + "' onchange='PluginUpdatesPage.setUpdateClass(this);' data-inline='true' id='" + fieldId + "' name='" + fieldId + "'>" + options + "</select>";
html += "</td>";
html += "</tr>";
elem.append(html).trigger('create');
},
getHtmlOptions: function (names, selectedValue) {
var html = "";
for (var i = 0, length = names.length; i < length; i++) {
var name = names[i];
if (name == selectedValue) {
html += '<option value="' + name + '" selected="selected">' + name + '</option>';
} else {
html += '<option value="' + name + '">' + name + '</option>';
}
}
return html;
},
setAutoUpdate: function (select) {
var id = $(select).attr('data-id');
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(id).done(function (config) {
config.EnableAutoUpdate = select.selectedIndex === 1;
ApiClient.updatePluginConfiguration(id, config).done(Dashboard.hideLoadingMsg);
});
},
setUpdateClass: function (select) {
var id = $(select).attr('data-id');
Dashboard.showLoadingMsg();
ApiClient.getPluginConfiguration(id).done(function (config) {
config.UpdateClass = select.value;
ApiClient.updatePluginConfiguration(id, config).done(Dashboard.hideLoadingMsg);
});
}
};
$(document).on('pageshow', "#pluginUpdatesPage", PluginUpdatesPage.onPageShow);

View file

@ -0,0 +1,86 @@
var PluginsPage = {
onPageShow: function () {
PluginsPage.reloadList();
},
reloadList: function () {
Dashboard.showLoadingMsg();
var promise1 = ApiClient.getInstalledPlugins();
var promise2 = $.getJSON("configurationpages?pageType=PluginConfiguration");
$.when(promise1, promise2).done(function(response1, response2) {
PluginsPage.populateList(response1[0], response2[0]);
});
},
populateList: function (plugins, pluginConfigurationPages) {
var page = $($.mobile.activePage);
plugins = plugins.sort(function (plugin1, plugin2) {
return (plugin1.Name) > (plugin2.Name) ? 1 : -1;
});
var html = "";
for (var i = 0, length = plugins.length; i < length; i++) {
var plugin = plugins[i];
var configPage = $.grep(pluginConfigurationPages, function (pluginConfigurationPage) {
return pluginConfigurationPage.PluginId == plugin.Id;
})[0];
html += "<li>";
var href = configPage ? Dashboard.getConfigurationPageUrl(configPage.Name) : "#";
html += "<a href='" + href + "'>";
html += "<h3>" + plugin.Name + "</h3>";
html += "<p><strong>" + plugin.Version + "</strong></p>";
html += "</a>";
html += "<a data-id='" + plugin.Id + "' data-pluginname='" + plugin.Name + "' onclick='PluginsPage.deletePlugin(this);' href='#'>Delete</a>";
html += "</li>";
}
$('#ulInstalledPlugins', page).html(html).listview('refresh');
Dashboard.hideLoadingMsg();
},
deletePlugin: function (link) {
var name = link.getAttribute('data-pluginname');
var uniqueid = link.getAttribute('data-id');
var msg = "Are you sure you wish to uninstall " + name + "?";
Dashboard.confirm(msg, "Uninstall Plugin", function (result) {
if (result) {
Dashboard.showLoadingMsg();
ApiClient.uninstallPlugin(uniqueid).done(function () {
PluginsPage.reloadList();
});
}
});
}
};
$(document).on('pageshow', "#pluginsPage", PluginsPage.onPageShow);

View file

@ -0,0 +1,294 @@
var ScheduledTaskPage = {
onPageShow: function () {
ScheduledTaskPage.refreshScheduledTask();
},
refreshScheduledTask: function () {
Dashboard.showLoadingMsg();
var id = getParameterByName('id');
ApiClient.getScheduledTask(id).done(ScheduledTaskPage.loadScheduledTask);
},
loadScheduledTask: function (task) {
Dashboard.setPageTitle(task.Name);
$('#pTaskDescription', $.mobile.activePage).html(task.Description);
ScheduledTaskPage.loadTaskTriggers(task);
Dashboard.hideLoadingMsg();
},
loadTaskTriggers: function (task) {
var html = '';
html += '<li data-role="list-divider"><h3>Task Triggers</h3></li>';
for (var i = 0, length = task.Triggers.length; i < length; i++) {
var trigger = task.Triggers[i];
html += '<li>';
html += '<a href="#">';
html += ScheduledTaskPage.getTriggerFriendlyName(trigger);
html += '</a>';
html += '<a href="#" onclick="ScheduledTaskPage.confirmDeleteTrigger(' + i + ');">Delete</a>';
html += '</li>';
}
$('#ulTaskTriggers', $.mobile.activePage).html(html).listview('refresh');
},
getTriggerFriendlyName: function (trigger) {
if (trigger.Type == 'DailyTrigger') {
return 'Daily at ' + ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks);
}
if (trigger.Type == 'WeeklyTrigger') {
return trigger.DayOfWeek + 's at ' + ScheduledTaskPage.getDisplayTime(trigger.TimeOfDayTicks);
}
if (trigger.Type == 'SystemEventTrigger') {
if (trigger.SystemEvent == 'WakeFromSleep') {
return 'On wake from sleep';
}
}
if (trigger.Type == 'IntervalTrigger') {
var hours = trigger.IntervalTicks / 36000000000;
if (hours == .25) {
return "Every 15 minutes";
}
if (hours == .5) {
return "Every 30 minutes";
}
if (hours == .75) {
return "Every 45 minutes";
}
if (hours == 1) {
return "Every hour";
}
return 'Every ' + hours + ' hours';
}
if (trigger.Type == 'StartupTrigger') {
return 'On application startup';
}
return trigger.Type;
},
getDisplayTime: function (ticks) {
var hours = ticks / 36000000000;
if (hours < 1) {
hours = 0;
}
hours = parseInt(hours);
ticks -= (hours * 36000000000);
var minutes = parseInt(ticks / 600000000);
var suffix = "am";
if (hours > 11) {
suffix = "pm";
}
hours = hours % 12;
if (hours == 0) {
hours = 12;
}
if (minutes < 10) {
minutes = '0' + minutes;
}
return hours + ':' + minutes + ' ' + suffix;
},
showAddTriggerPopup: function () {
var page = $.mobile.activePage;
$('#selectTriggerType', page).val('DailyTrigger').trigger('change').selectmenu('refresh');
$('#popupAddTrigger', page).popup("open").on("popupafterclose", function () {
$('#addTriggerForm', page).off("submit");
$(this).off("popupafterclose");
});
$('#addTriggerForm', page).on('submit', function () {
ScheduledTaskPage.addTrigger();
return false;
});
},
addTrigger: function () {
Dashboard.showLoadingMsg();
var id = getParameterByName('id');
ApiClient.getScheduledTask(id).done(function (task) {
task.Triggers.push(ScheduledTaskPage.getTriggerToAdd());
ApiClient.updateScheduledTaskTriggers(task.Id, task.Triggers).done(function () {
$('#popupAddTrigger').popup('close');
ScheduledTaskPage.refreshScheduledTask();
});
});
},
confirmDeleteTrigger: function (index) {
Dashboard.confirm("Are you sure you wish to delete this task trigger?", "Delete Task Trigger", function (result) {
if (result) {
ScheduledTaskPage.deleteTrigger(index);
}
});
},
deleteTrigger: function (index) {
Dashboard.showLoadingMsg();
var id = getParameterByName('id');
ApiClient.getScheduledTask(id).done(function (task) {
task.Triggers.remove(index);
ApiClient.updateScheduledTaskTriggers(task.Id, task.Triggers).done(function () {
ScheduledTaskPage.refreshScheduledTask();
});
});
},
refreshTriggerFields: function (triggerType) {
var page = $.mobile.activePage;
if (triggerType == 'DailyTrigger') {
$('#fldTimeOfDay', page).show();
$('#fldDayOfWeek', page).hide();
$('#fldSelectSystemEvent', page).hide();
$('#fldSelectInterval', page).hide();
$('#txtTimeOfDay', page).attr('required', 'required');
}
else if (triggerType == 'WeeklyTrigger') {
$('#fldTimeOfDay', page).show();
$('#fldDayOfWeek', page).show();
$('#fldSelectSystemEvent', page).hide();
$('#fldSelectInterval', page).hide();
$('#txtTimeOfDay', page).attr('required', 'required');
}
else if (triggerType == 'SystemEventTrigger') {
$('#fldTimeOfDay', page).hide();
$('#fldDayOfWeek', page).hide();
$('#fldSelectSystemEvent', page).show();
$('#fldSelectInterval', page).hide();
$('#txtTimeOfDay', page).removeAttr('required');
}
else if (triggerType == 'IntervalTrigger') {
$('#fldTimeOfDay', page).hide();
$('#fldDayOfWeek', page).hide();
$('#fldSelectSystemEvent', page).hide();
$('#fldSelectInterval', page).show();
$('#txtTimeOfDay', page).removeAttr('required');
}
else if (triggerType == 'StartupTrigger') {
$('#fldTimeOfDay', page).hide();
$('#fldDayOfWeek', page).hide();
$('#fldSelectSystemEvent', page).hide();
$('#fldSelectInterval', page).hide();
$('#txtTimeOfDay', page).removeAttr('required');
}
},
getTriggerToAdd: function () {
var page = $.mobile.activePage;
var trigger = {
Type: $('#selectTriggerType', page).val()
};
if (trigger.Type == 'DailyTrigger') {
trigger.TimeOfDayTicks = ScheduledTaskPage.getTimeOfDayTicks($('#txtTimeOfDay', page).val());
}
else if (trigger.Type == 'WeeklyTrigger') {
trigger.DayOfWeek = $('#selectDayOfWeek', page).val();
trigger.TimeOfDayTicks = ScheduledTaskPage.getTimeOfDayTicks($('#txtTimeOfDay', page).val());
}
else if (trigger.Type == 'SystemEventTrigger') {
trigger.SystemEvent = $('#selectSystemEvent', page).val();
}
else if (trigger.Type == 'IntervalTrigger') {
trigger.IntervalTicks = $('#selectInterval', page).val();
}
return trigger;
},
getTimeOfDayTicks: function (val) {
var vals = val.split(':');
var hours = vals[0];
var minutes = vals[1];
// Add hours
var ticks = hours * 60 * 60 * 1000 * 10000;
ticks += minutes * 60 * 1000 * 10000;
return ticks;
}
};
$(document).on('pageshow', "#scheduledTaskPage", ScheduledTaskPage.onPageShow);

View file

@ -0,0 +1,169 @@
var ScheduledTasksPage = {
onPageShow: function () {
Dashboard.showLoadingMsg();
ScheduledTasksPage.reloadList(true);
$(ApiClient).on("websocketmessage", ScheduledTasksPage.onWebSocketMessage).on("websocketopen", ScheduledTasksPage.onWebSocketConnectionChange).on("websocketerror", ScheduledTasksPage.onWebSocketConnectionChange).on("websocketclose", ScheduledTasksPage.onWebSocketConnectionChange);
},
onPageHide: function () {
$(ApiClient).off("websocketmessage", ScheduledTasksPage.onWebSocketMessage).off("websocketopen", ScheduledTasksPage.onWebSocketConnectionChange).off("websocketerror", ScheduledTasksPage.onWebSocketConnectionChange).off("websocketclose", ScheduledTasksPage.onWebSocketConnectionChange);
ScheduledTasksPage.stopInterval();
},
startInterval: function () {
if (ApiClient.isWebSocketOpen()) {
ApiClient.sendWebSocketMessage("ScheduledTasksInfoStart", "1500,1500");
}
},
stopInterval: function () {
if (ApiClient.isWebSocketOpen()) {
ApiClient.sendWebSocketMessage("ScheduledTasksInfoStop");
}
},
onWebSocketMessage: function (e, msg) {
if (msg.MessageType == "ScheduledTasksInfo") {
ScheduledTasksPage.populateList(msg.Data);
}
},
onWebSocketConnectionChange: function() {
ScheduledTasksPage.reloadList(true);
},
reloadList: function (updateInterval) {
if (updateInterval) {
ScheduledTasksPage.stopInterval();
}
ApiClient.getScheduledTasks().done(function (tasks) {
ScheduledTasksPage.populateList(tasks);
Dashboard.hideLoadingMsg();
if (updateInterval) {
ScheduledTasksPage.startInterval();
}
});
},
populateList: function (tasks) {
tasks = tasks.sort(function (a, b) {
a = a.Category + " " + a.Name;
b = b.Category + " " + b.Name;
if (a == b) {
return 0;
}
if (a < b) {
return -1;
}
return 1;
});
var page = $($.mobile.activePage);
var html = "";
var currentCategory;
for (var i = 0, length = tasks.length; i < length; i++) {
var task = tasks[i];
if (task.Category != currentCategory) {
currentCategory = task.Category;
html += "<li data-role='list-divider'>" + currentCategory + "</li>";
}
html += "<li>";
html += "<a href='scheduledTask.html?id=" + task.Id + "'>";
html += "<h3>" + task.Name + "</h3>";
if (task.State == "Idle") {
if (task.LastExecutionResult) {
var text = "Last ran " + humane_date(task.LastExecutionResult.EndTimeUtc) + ', taking ' + humane_elapsed(task.LastExecutionResult.StartTimeUtc, task.LastExecutionResult.EndTimeUtc);
if (task.LastExecutionResult.Status == "Failed") {
text += " <span style='color:#FF0000;'>(failed)</span>";
}
else if (task.LastExecutionResult.Status == "Cancelled") {
text += " <span style='color:#0026FF;'>(cancelled)</span>";
}
else if (task.LastExecutionResult.Status == "Aborted") {
text += " <span style='color:#FF0000;'>(Aborted by server shutdown)</span>";
}
html += "<p>" + text + "</p>";
}
html += "<a href='#' data-icon='play' onclick='ScheduledTasksPage.startTask(\"" + task.Id + "\");'>Start</a>";
}
else if (task.State == "Running") {
var progress = Math.round(task.CurrentProgressPercentage || 0);
html += '<p><progress max="100" value="' + progress + '" title="' + progress + '%">';
html += '' + progress + '%';
html += '</progress>';
html += "<span style='color:#009F00;margin-left:5px;'>" + progress + "%</span>";
html += '</p>';
html += "<a href='#' data-icon='stop' onclick='ScheduledTasksPage.stopTask(\"" + task.Id + "\");'>Stop</a>";
} else {
html += "<p style='color:#FF0000;'>Stopping</p>";
html += "<a href='#' data-icon='play' style='visibility:hidden;'>Start</a>";
}
html += "</a>";
html += "</li>";
}
$('#ulScheduledTasks', page).html(html).listview('refresh');
},
startTask: function (id) {
Dashboard.showLoadingMsg();
ApiClient.startScheduledTask(id).done(function (result) {
ScheduledTasksPage.reloadList();
});
},
stopTask: function (id) {
Dashboard.showLoadingMsg();
ApiClient.stopScheduledTask(id).done(function (result) {
ScheduledTasksPage.reloadList();
});
}
};
$(document).on('pageshow', "#scheduledTasksPage", ScheduledTasksPage.onPageShow).on('pagehide', "#scheduledTasksPage", ScheduledTasksPage.onPageHide);

View file

@ -0,0 +1,77 @@
var SupporterKeyPage = {
onPageShow: function () {
SupporterKeyPage.load();
},
onPageHide: function () {
},
load: function() {
Dashboard.showLoadingMsg();
var page = $.mobile.activePage;
ApiClient.getPluginSecurityInfo().done(function (info) {
$('#txtSupporterKey', page).val(info.SupporterKey);
$('#txtLegacyKey', page).val(info.LegacyKey);
if (info.IsMBSupporter) {
$('.supporterOnly', page).show();
} else {
$('.supporterOnly', page).hide();
}
Dashboard.hideLoadingMsg();
});
},
updateSupporterKey: function () {
Dashboard.showLoadingMsg();
var page = $.mobile.activePage;
var key = $('#txtSupporterKey', page).val();
var legacyKey = $('#txtLegacyKey', page).val();
var info = {
SupporterKey: key,
LegacyKey: legacyKey
};
ApiClient.updatePluginSecurityInfo(info).done(function () {
Dashboard.resetPluginSecurityInfo();
Dashboard.hideLoadingMsg();
SupporterPage.load();
});
return false;
},
retrieveSupporterKey: function () {
Dashboard.showLoadingMsg();
var page = $.mobile.activePage;
var email = $('#txtEmail', page).val();
var url = "http://mb3admin.com/admin/service/supporter/retrievekey?email="+email;
console.log(url);
$.post(url).done(function (res) {
var result = JSON.parse(res);
Dashboard.hideLoadingMsg();
if (result.Success) {
Dashboard.alert("Key emailed to "+email);
} else {
Dashboard.showError(result.ErrorMessage);
}
console.log(result);
});
return false;
}
};
$(document).on('pageshow', "#supporterKeyPage", SupporterKeyPage.onPageShow)
.on('pagehide', "#supporterKeyPage", SupporterKeyPage.onPageHide);

View file

@ -0,0 +1,29 @@
var SupporterPage = {
onPageShow: function () {
SupporterPage.load();
},
onPageHide: function () {
},
load: function() {
Dashboard.showLoadingMsg();
var page = $.mobile.activePage;
ApiClient.getPluginSecurityInfo().done(function (info) {
$('#txtSupporterKey', page).val(info.SupporterKey);
if (info.IsMBSupporter) {
$('.supporterOnly', page).show();
} else {
$('.supporterOnly', page).hide();
}
$('#paypalReturnUrl', page).val(ApiClient.getCustomUrl("dashboard/supporterKey.html"));
Dashboard.hideLoadingMsg();
});
}
};
$(document).on('pageshow', "#supporterPage", SupporterPage.onPageShow)
.on('pagehide', "#supporterPage", SupporterPage.onPageHide);

View file

@ -0,0 +1,88 @@
var UpdatePasswordPage = {
onPageShow: function () {
UpdatePasswordPage.loadUser();
},
loadUser: function() {
var page = $.mobile.activePage;
var userid = getParameterByName("userId");
ApiClient.getUser(userid).done(function (user) {
Dashboard.setPageTitle(user.Name);
if (user.HasPassword) {
$('#btnResetPassword', page).show();
} else {
$('#btnResetPassword', page).hide();
}
});
$('#txtCurrentPassword', page).val('');
$('#txtNewPassword', page).val('');
$('#txtNewPasswordConfirm', page).val('');
},
save: function () {
var userId = getParameterByName("userId");
var page = $($.mobile.activePage);
var currentPassword = $('#txtCurrentPassword', page).val();
var newPassword = $('#txtNewPassword', page).val();
ApiClient.updateUserPassword(userId, currentPassword, newPassword).done(UpdatePasswordPage.saveComplete);
},
saveComplete: function () {
Dashboard.hideLoadingMsg();
Dashboard.alert("Password saved.");
UpdatePasswordPage.loadUser();
},
resetPassword: function () {
var msg = "Are you sure you wish to reset the password?";
Dashboard.confirm(msg, "Password Reset", function (result) {
if (result) {
var userId = getParameterByName("userId");
Dashboard.showLoadingMsg();
ApiClient.resetUserPassword(userId).done(function () {
Dashboard.hideLoadingMsg();
Dashboard.alert("The password has been reset.");
UpdatePasswordPage.loadUser();
});
}
});
},
onSubmit: function () {
var page = $($.mobile.activePage);
if ($('#txtNewPassword', page).val() != $('#txtNewPasswordConfirm', page).val()) {
Dashboard.showError("Password and password confirmation must match.");
return false;
}
Dashboard.showLoadingMsg();
UpdatePasswordPage.save();
// Disable default form submission
return false;
}
};
$(document).on('pageshow', "#updatePasswordPage", UpdatePasswordPage.onPageShow);

View file

@ -0,0 +1,181 @@
var UserImagePage = {
onPageShow: function () {
UserImagePage.reloadUser();
$("#userImageDropZone", this).on('dragover', UserImagePage.onImageDragOver).on('drop', UserImagePage.onImageDrop);
},
onPageHide: function () {
$("#userImageDropZone", this).off('dragover', UserImagePage.onImageDragOver).off('drop', UserImagePage.onImageDrop);
},
reloadUser: function () {
var userId = getParameterByName("userId");
Dashboard.showLoadingMsg();
ApiClient.getUser(userId).done(function (user) {
var page = $($.mobile.activePage);
$('#uploadUserImage', page).val('').trigger('change');
Dashboard.setPageTitle(user.Name);
if (user.PrimaryImageTag) {
var imageUrl = ApiClient.getUserImageUrl(user.Id, {
height: 450,
tag: user.PrimaryImageTag,
type: "Primary"
});
$('#fldImage', page).show().html('').html("<img height='200px' src='" + imageUrl + "' />");
$('#fldDeleteImage', page).show();
$('#headerUploadNewImage', page).show();
} else {
$('#fldImage', page).hide().html('');
$('#fldDeleteImage', page).hide();
$('#headerUploadNewImage', page).hide();
}
Dashboard.hideLoadingMsg();
});
},
deleteImage: function () {
Dashboard.confirm("Are you sure you wish to delete the image?", "Delete Image", function (result) {
if (result) {
Dashboard.showLoadingMsg();
var userId = getParameterByName("userId");
ApiClient.deleteUserImage(userId, "primary").done(UserImagePage.processImageChangeResult);
}
});
},
processImageChangeResult: function () {
Dashboard.hideLoadingMsg();
Dashboard.validateCurrentUser();
UserImagePage.reloadUser();
},
onFileUploadChange: function (fileUpload) {
UserImagePage.setFiles(fileUpload.files);
},
setFiles: function (files) {
var page = $.mobile.activePage;
var file = files[0];
if (!file || !file.type.match('image.*')) {
$('#userImageOutput', page).html('');
$('#fldUpload', page).hide();
UserImagePage.currentFile = null;
return;
}
UserImagePage.currentFile = file;
var reader = new FileReader();
reader.onerror = UserImagePage.onFileReaderError;
reader.onloadstart = UserImagePage.onFileReaderOnloadStart;
reader.onabort = UserImagePage.onFileReaderAbort;
// Closure to capture the file information.
reader.onload = (function (theFile) {
return function (e) {
// Render thumbnail.
var html = ['<img style="max-width:500px;max-height:200px;" src="', e.target.result, '" title="', escape(theFile.name), '"/>'].join('');
$('#userImageOutput', page).html(html);
$('#fldUpload', page).show();
};
})(file);
// Read in the image file as a data URL.
reader.readAsDataURL(file);
},
onFileReaderError: function (evt) {
Dashboard.hideLoadingMsg();
switch (evt.target.error.code) {
case evt.target.error.NOT_FOUND_ERR:
Dashboard.showError('File Not Found!');
break;
case evt.target.error.NOT_READABLE_ERR:
Dashboard.showError('File is not readable');
break;
case evt.target.error.ABORT_ERR:
break; // noop
default:
Dashboard.showError('An error occurred reading this file.');
};
},
onFileReaderOnloadStart: function (evt) {
$('#fldUpload', $.mobile.activePage).hide();
},
onFileReaderAbort: function (evt) {
Dashboard.hideLoadingMsg();
Dashboard.showError('File read cancelled');
},
onSubmit: function () {
var file = UserImagePage.currentFile;
if (!file || !file.type.match('image.*')) {
return false;
}
Dashboard.showLoadingMsg();
var userId = getParameterByName("userId");
ApiClient.uploadUserImage(userId, 'Primary', file).done(UserImagePage.processImageChangeResult);
return false;
},
onImageDrop: function (e) {
e.preventDefault();
UserImagePage.setFiles(e.originalEvent.dataTransfer.files);
return false;
},
onImageDragOver: function (e) {
e.preventDefault();
e.originalEvent.dataTransfer.dropEffect = 'Copy';
return false;
}
};
$(document).on('pageshow', "#userImagePage", UserImagePage.onPageShow).on('pagehide', "#userImagePage", UserImagePage.onPageHide);

View file

@ -0,0 +1,76 @@
var UserProfilesPage = {
onPageShow: function () {
UserProfilesPage.loadPageData();
},
loadPageData: function () {
Dashboard.showLoadingMsg();
ApiClient.getUsers().done(UserProfilesPage.renderUsers);
},
renderUsers: function (users) {
var html = "";
html += '<li data-role="list-divider"><h3>Users</h3></li>';
for (var i = 0, length = users.length; i < length; i++) {
var user = users[i];
html += "<li>";
html += "<a onclick='Dashboard.navigate(\"editUser.html?userId=" + user.Id + "\");' href='#'>";
if (user.PrimaryImageTag) {
var url = ApiClient.getUserImageUrl(user.Id, {
width: 225,
tag: user.PrimaryImageTag,
type: "Primary"
});
html += "<img src='" + url + "' />";
} else {
html += "<img src='css/images/userFlyoutDefault.png' />";
}
html += "<h3>" + user.Name + "</h3>";
html += "</a>";
html += "<a onclick='UserProfilesPage.deleteUser(this);' data-userid='" + user.Id + "' data-username='" + user.Name + "' href='#'>Delete</a>";
html += "</li>";
}
$('#ulUserProfiles', $('#userProfilesPage')).html(html).listview('refresh');
Dashboard.hideLoadingMsg();
},
deleteUser: function (link) {
var name = link.getAttribute('data-username');
var msg = "Are you sure you wish to delete " + name + "?";
Dashboard.confirm(msg, "Delete User", function (result) {
if (result) {
Dashboard.showLoadingMsg();
var id = link.getAttribute('data-userid');
ApiClient.deleteUser(id).done(function () {
Dashboard.validateCurrentUser();
UserProfilesPage.loadPageData();
});
}
});
}
};
$(document).on('pageshow', "#userProfilesPage", UserProfilesPage.onPageShow);

View file

@ -0,0 +1,16 @@
var WizardFinishPage = {
onFinish: function() {
ApiClient.getServerConfiguration().done(function (config) {
config.IsStartupWizardCompleted = true;
ApiClient.updateServerConfiguration(config).done(function() {
Dashboard.navigate('dashboard.html');
});
});
}
};

View file

@ -0,0 +1,17 @@
var WizardStartPage = {
gotoNextPage: function () {
ApiClient.getUsers().done(function (users) {
if (users.length > 1) {
Dashboard.navigate('wizardLibrary.html');
} else {
Dashboard.navigate('wizardUser.html');
}
});
}
};

View file

@ -0,0 +1,59 @@
var WizardUserPage = {
onPageShow: function () {
Dashboard.showLoadingMsg();
var page = this;
ApiClient.getUsers().done(function (users) {
var user = users[0] || { Name: "User" };
$('#txtUsername', page).val(user.Name);
Dashboard.hideLoadingMsg();
});
},
onSubmit: function() {
Dashboard.showLoadingMsg();
var page = $.mobile.activePage;
ApiClient.getUsers().done(function (users) {
var user;
if (users.length) {
user = users[0];
user.Name = $('#txtUsername', page).val();
ApiClient.updateUser(user).done(WizardUserPage.saveComplete);
} else {
user = { Name: $('#txtUsername', page).val() };
ApiClient.createUser(user).done(WizardUserPage.saveComplete);
}
});
return false;
},
saveComplete: function () {
Dashboard.hideLoadingMsg();
Dashboard.navigate('wizardLibrary.html');
}
};
$(document).on('pageshow', "#wizardUserPage", WizardUserPage.onPageShow);

View file

@ -0,0 +1,24 @@
var AboutPage = {
onPageShow: function () {
AboutPage.pollForInfo();
},
pollForInfo: function () {
ApiClient.getSystemInfo().done(AboutPage.renderInfo);
},
renderInfo: function (info) {
AboutPage.renderSystemInfo(info);
},
renderSystemInfo: function (info) {
var page = $.mobile.activePage;
$('#appVersionNumber', page).html(info.Version);
},
};
$(document).on('pageshow', "#aboutPage", AboutPage.onPageShow);

1174
dashboard-ui/scripts/site.js Normal file

File diff suppressed because it is too large Load diff