diff options
Diffstat (limited to 'MediaBrowser.WebDashboard')
133 files changed, 9341 insertions, 119 deletions
diff --git a/MediaBrowser.WebDashboard/Api/DashboardInfo.cs b/MediaBrowser.WebDashboard/Api/DashboardInfo.cs new file mode 100644 index 0000000000..a11e565bc6 --- /dev/null +++ b/MediaBrowser.WebDashboard/Api/DashboardInfo.cs @@ -0,0 +1,45 @@ +using MediaBrowser.Model.Connectivity; +using MediaBrowser.Model.DTO; +using MediaBrowser.Model.System; +using MediaBrowser.Model.Tasks; +using System; + +namespace MediaBrowser.WebDashboard.Api +{ + /// <summary> + /// Class DashboardInfo + /// </summary> + public class DashboardInfo + { + /// <summary> + /// Gets or sets the system info. + /// </summary> + /// <value>The system info.</value> + public SystemInfo SystemInfo { get; set; } + + /// <summary> + /// Gets or sets the running tasks. + /// </summary> + /// <value>The running tasks.</value> + public TaskInfo[] RunningTasks { get; set; } + + /// <summary> + /// Gets or sets the application update task id. + /// </summary> + /// <value>The application update task id.</value> + public Guid ApplicationUpdateTaskId { get; set; } + + /// <summary> + /// Gets or sets the active connections. + /// </summary> + /// <value>The active connections.</value> + public ClientConnectionInfo[] ActiveConnections { get; set; } + + /// <summary> + /// Gets or sets the users. + /// </summary> + /// <value>The users.</value> + public DtoUser[] Users { get; set; } + } + +} diff --git a/MediaBrowser.WebDashboard/Api/DashboardInfoWebSocketListener.cs b/MediaBrowser.WebDashboard/Api/DashboardInfoWebSocketListener.cs new file mode 100644 index 0000000000..2463e440e5 --- /dev/null +++ b/MediaBrowser.WebDashboard/Api/DashboardInfoWebSocketListener.cs @@ -0,0 +1,33 @@ +using MediaBrowser.Common.Kernel; +using MediaBrowser.Controller; +using System.ComponentModel.Composition; +using System.Threading.Tasks; + +namespace MediaBrowser.WebDashboard.Api +{ + /// <summary> + /// Class DashboardInfoWebSocketListener + /// </summary> + [Export(typeof(IWebSocketListener))] + class DashboardInfoWebSocketListener : BasePeriodicWebSocketListener<IKernel, DashboardInfo, object> + { + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + protected override string Name + { + get { return "DashboardInfo"; } + } + + /// <summary> + /// Gets the data to send. + /// </summary> + /// <param name="state">The state.</param> + /// <returns>Task{IEnumerable{TaskInfo}}.</returns> + protected override Task<DashboardInfo> GetDataToSend(object state) + { + return Task.FromResult(DashboardService.GetDashboardInfo((Kernel)Kernel)); + } + } +} diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs new file mode 100644 index 0000000000..50472423e0 --- /dev/null +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -0,0 +1,447 @@ +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Net; +using MediaBrowser.Common.ScheduledTasks; +using MediaBrowser.Common.ScheduledTasks.Tasks; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Model.Tasks; +using ServiceStack.ServiceHost; +using ServiceStack.WebHost.Endpoints; +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace MediaBrowser.WebDashboard.Api +{ + /// <summary> + /// Class GetDashboardConfigurationPages + /// </summary> + [Route("/dashboard/ConfigurationPages", "GET")] + public class GetDashboardConfigurationPages : IReturn<List<BaseConfigurationPage>> + { + /// <summary> + /// Gets or sets the type of the page. + /// </summary> + /// <value>The type of the page.</value> + public ConfigurationPageType? PageType { get; set; } + } + + /// <summary> + /// Class GetDashboardConfigurationPage + /// </summary> + [Route("/dashboard/ConfigurationPage", "GET")] + public class GetDashboardConfigurationPage : IReturn<BaseConfigurationPage> + { + /// <summary> + /// Gets or sets the name. + /// </summary> + /// <value>The name.</value> + public string Name { get; set; } + } + + /// <summary> + /// Class GetDashboardResource + /// </summary> + public class GetDashboardResource + { + /// <summary> + /// Gets or sets the name. + /// </summary> + /// <value>The name.</value> + public string Name { get; set; } + /// <summary> + /// Gets or sets the V. + /// </summary> + /// <value>The V.</value> + public string V { get; set; } + } + + /// <summary> + /// Class GetDashboardInfo + /// </summary> + [Route("/dashboard/dashboardInfo", "GET")] + public class GetDashboardInfo : IReturn<DashboardInfo> + { + } + + /// <summary> + /// Class DashboardService + /// </summary> + [Export(typeof(IRestfulService))] + public class DashboardService : BaseRestService + { + /// <summary> + /// Adds the routes. + /// </summary> + /// <param name="appHost">The app host.</param> + public override void Configure(IAppHost appHost) + { + base.Configure(appHost); + + appHost.Routes.Add<GetDashboardResource>("/dashboard/{name*}", "GET"); + } + + /// <summary> + /// Gets the specified request. + /// </summary> + /// <param name="request">The request.</param> + /// <returns>System.Object.</returns> + public object Get(GetDashboardInfo request) + { + var kernel = (Kernel)Kernel; + + return GetDashboardInfo(kernel); + } + + /// <summary> + /// Gets the dashboard info. + /// </summary> + /// <param name="kernel">The kernel.</param> + /// <returns>DashboardInfo.</returns> + public static DashboardInfo GetDashboardInfo(Kernel kernel) + { + var connections = kernel.UserManager.ActiveConnections.ToArray(); + + return new DashboardInfo + { + SystemInfo = kernel.GetSystemInfo(), + + RunningTasks = kernel.ScheduledTasks.Where(i => i.State == TaskState.Running || i.State == TaskState.Cancelling) + .Select(ScheduledTaskHelpers.GetTaskInfo) + .ToArray(), + + ApplicationUpdateTaskId = kernel.ScheduledTasks.OfType<SystemUpdateTask>().First().Id, + + ActiveConnections = connections, + + Users = kernel.Users.Where(u => connections.Any(c => c.UserId == u.Id)).Select(DtoBuilder.GetDtoUser).ToArray() + }; + } + + /// <summary> + /// Gets the specified request. + /// </summary> + /// <param name="request">The request.</param> + /// <returns>System.Object.</returns> + public object Get(GetDashboardConfigurationPage request) + { + var kernel = (Kernel)Kernel; + + var page = kernel.PluginConfigurationPages.First(p => p.Name.Equals(request.Name, StringComparison.OrdinalIgnoreCase)); + var plugin = page.GetOwnerPlugin(); + + return ToStaticResult(plugin.Version.ToString().GetMD5(), plugin.AssemblyDateLastModified, null, MimeTypes.GetMimeType("page.html"), () => ModifyHtml(page.GetHtmlStream())); + } + + /// <summary> + /// Gets the specified request. + /// </summary> + /// <param name="request">The request.</param> + /// <returns>System.Object.</returns> + public object Get(GetDashboardConfigurationPages request) + { + var kernel = (Kernel)Kernel; + + var pages = kernel.PluginConfigurationPages; + + if (request.PageType.HasValue) + { + pages = pages.Where(p => p.ConfigurationPageType == request.PageType.Value); + } + + return ToOptimizedResult(pages.ToList()); + } + + /// <summary> + /// Gets the specified request. + /// </summary> + /// <param name="request">The request.</param> + /// <returns>System.Object.</returns> + public object Get(GetDashboardResource request) + { + var path = request.Name; + + var contentType = MimeTypes.GetMimeType(path); + + TimeSpan? cacheDuration = null; + + // Cache images unconditionally - updates to image files will require new filename + // If there's a version number in the query string we can cache this unconditionally + if (contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase) || !string.IsNullOrEmpty(request.V)) + { + cacheDuration = TimeSpan.FromDays(365); + } + + var assembly = GetType().Assembly.GetName(); + + return ToStaticResult(assembly.Version.ToString().GetMD5(), null, cacheDuration, contentType, () => GetResourceStream(path)); + } + + /// <summary> + /// Gets the resource stream. + /// </summary> + /// <param name="path">The path.</param> + /// <returns>Task{Stream}.</returns> + private async Task<Stream> GetResourceStream(string path) + { + Stream resourceStream; + + if (path.Equals("scripts/all.js", StringComparison.OrdinalIgnoreCase)) + { + resourceStream = await GetAllJavascript().ConfigureAwait(false); + } + else + { + resourceStream = GetType().Assembly.GetManifestResourceStream("MediaBrowser.WebDashboard.Html." + ConvertUrlToResourcePath(path)); + } + + if (resourceStream != null) + { + var isHtml = IsHtml(path); + + // Don't apply any caching for html pages + // jQuery ajax doesn't seem to handle if-modified-since correctly + if (isHtml) + { + resourceStream = await ModifyHtml(resourceStream).ConfigureAwait(false); + } + } + + return resourceStream; + } + + /// <summary> + /// Redirects the specified CTX. + /// </summary> + /// <param name="ctx">The CTX.</param> + /// <param name="url">The URL.</param> + private void Redirect(HttpListenerContext ctx, string url) + { + // Try to prevent the browser from caching the redirect response (the right way) + ctx.Response.Headers[HttpResponseHeader.CacheControl] = "no-cache, no-store, must-revalidate"; + ctx.Response.Headers[HttpResponseHeader.Pragma] = "no-cache, no-store, must-revalidate"; + ctx.Response.Headers[HttpResponseHeader.Expires] = "-1"; + + ctx.Response.Redirect(url); + ctx.Response.Close(); + } + + /// <summary> + /// Preserves the current query string when redirecting + /// </summary> + /// <param name="request">The request.</param> + /// <param name="newUrl">The new URL.</param> + /// <returns>System.String.</returns> + private string GetRedirectUrl(HttpListenerRequest request, string newUrl) + { + var query = request.Url.Query; + + return string.IsNullOrEmpty(query) ? newUrl : newUrl + query; + } + + /// <summary> + /// Converts the URL to a manifest resource path. + /// </summary> + /// <param name="url">The URL.</param> + /// <returns>System.String.</returns> + private string ConvertUrlToResourcePath(string url) + { + var parts = url.Split('/'); + var normalizedParts = new string[parts.Length]; + + for (var i = 0; i < parts.Length; i++) + { + // We have to do some tricky string replacements for all parts of the path except the last + if (i < parts.Length - 1) + { + // Find the index of the first period as well as the first dash + var periodIndex = parts[i].IndexOf('.'); + var slashIndex = parts[i].IndexOf('-'); + + // Replace all periods with "._" and dashes with "_" + normalizedParts[i] = parts[i].Replace(".", "._").Replace("-", "_"); + + // If the first period occurred before the first slash, change it back from "._" to just "." + if (periodIndex < slashIndex) + { + var regex = new Regex("\\._"); + normalizedParts[i] = regex.Replace(normalizedParts[i], ".", 1); + } + } + else + { + normalizedParts[i] = parts[i]; + } + } + + return string.Join(".", normalizedParts); + } + + /// <summary> + /// Determines whether the specified path is HTML. + /// </summary> + /// <param name="path">The path.</param> + /// <returns><c>true</c> if the specified path is HTML; otherwise, <c>false</c>.</returns> + private bool IsHtml(string path) + { + return Path.GetExtension(path).EndsWith("html", StringComparison.OrdinalIgnoreCase); + } + + /// <summary> + /// Modifies the HTML by adding common meta tags, css and js. + /// </summary> + /// <param name="sourceStream">The source stream.</param> + /// <returns>Task{Stream}.</returns> + internal async Task<Stream> ModifyHtml(Stream sourceStream) + { + string html; + + using (var memoryStream = new MemoryStream()) + { + await sourceStream.CopyToAsync(memoryStream).ConfigureAwait(false); + + html = Encoding.UTF8.GetString(memoryStream.ToArray()); + } + + var version = GetType().Assembly.GetName().Version; + + html = html.Replace("<head>", "<head>" + GetMetaTags() + GetCommonCss(version) + GetCommonJavascript(version)); + + var bytes = Encoding.UTF8.GetBytes(html); + + sourceStream.Dispose(); + + return new MemoryStream(bytes); + } + + /// <summary> + /// Gets the meta tags. + /// </summary> + /// <returns>System.String.</returns> + private static string GetMetaTags() + { + var sb = new StringBuilder(); + + sb.Append("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">"); + sb.Append("<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">"); + sb.Append("<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\">"); + + // http://developer.apple.com/library/ios/#DOCUMENTATION/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html + sb.Append("<link rel=\"apple-touch-icon\" href=\"css/images/touchicon.png\" />"); + sb.Append("<link rel=\"apple-touch-icon\" sizes=\"72x72\" href=\"css/images/touchicon72.png\" />"); + sb.Append("<link rel=\"apple-touch-icon\" sizes=\"114x114\" href=\"css/images/touchicon114.png\" />"); + sb.Append("<link rel=\"apple-touch-startup-image\" href=\"css/images/iossplash.png\">"); + + return sb.ToString(); + } + + /// <summary> + /// Gets the common CSS. + /// </summary> + /// <returns>System.String.</returns> + private static string GetCommonCss(Version version) + { + var versionString = "?v=" + version; + + var files = new[] + { + "http://code.jquery.com/mobile/1.3.0-rc.1/jquery.mobile-1.3.0-rc.1.min.css", + "thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.css", + "css/site.css" + versionString + }; + + var tags = files.Select(s => string.Format("<link rel=\"stylesheet\" href=\"{0}\" />", s)).ToArray(); + + return string.Join(string.Empty, tags); + } + + /// <summary> + /// Gets the common javascript. + /// </summary> + /// <returns>System.String.</returns> + private static string GetCommonJavascript(Version version) + { + var versionString = "?v=" + version; + + var files = new[] + { + "http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js", + "http://code.jquery.com/mobile/1.3.0-rc.1/jquery.mobile-1.3.0-rc.1.min.js", + "../jsapiclient.js" + versionString, + "scripts/all.js" + versionString + }; + + var tags = files.Select(s => string.Format("<script src=\"{0}\"></script>", s)).ToArray(); + + return string.Join(string.Empty, tags); + } + + /// <summary> + /// Gets a stream containing all concatenated javascript + /// </summary> + /// <returns>Task{Stream}.</returns> + private async Task<Stream> GetAllJavascript() + { + const string resourcePrefix = "MediaBrowser.WebDashboard.Html.scripts."; + var assembly = GetType().Assembly; + + var scriptFiles = new[] + { + "Extensions.js", + "Site.js", + "AddPluginPage.js", + "AdvancedConfigurationPage.js", + "AdvancedMetadataConfigurationPage.js", + "PluginCatalogPage.js", + "DashboardPage.js", + "DisplaySettingsPage.js", + "EditUserPage.js", + "IndexPage.js", + "ItemDetailPage.js", + "LoginPage.js", + "LogPage.js", + "MediaLibraryPage.js", + "MediaPlayer.js", + "MetadataConfigurationPage.js", + "MetadataImagesPage.js", + "PluginsPage.js", + "PluginUpdatesPage.js", + "ScheduledTaskPage.js", + "ScheduledTasksPage.js", + "UpdatePasswordPage.js", + "UserImagePage.js", + "UserProfilesPage.js", + "WizardStartPage.js", + "WizardUserPage.js", + "SupporterKeyPage.js", + "SupporterPage.js" + }; + + var memoryStream = new MemoryStream(); + + var newLineBytes = Encoding.UTF8.GetBytes(Environment.NewLine); + + foreach (var file in scriptFiles) + { + using (var stream = assembly.GetManifestResourceStream(resourcePrefix + file)) + { + await stream.CopyToAsync(memoryStream).ConfigureAwait(false); + + await memoryStream.WriteAsync(newLineBytes, 0, newLineBytes.Length).ConfigureAwait(false); + } + } + + memoryStream.Position = 0; + return memoryStream; + } + + } + +} diff --git a/MediaBrowser.WebDashboard/Html/addPlugin.html b/MediaBrowser.WebDashboard/Html/addPlugin.html new file mode 100644 index 0000000000..820319091e --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/addPlugin.html @@ -0,0 +1,80 @@ +<!DOCTYPE html> +<html> +<head> + <title></title> +</head> +<body> + <div id="addPluginPage" data-role="page" class="page type-interior pluginConfigurationPage"> + + <div data-role="content"> + <div class="content-primary"> + <p> + <a data-role="button" data-icon="arrow-left" data-inline="true" data-mini="true" data-theme="b" href="pluginCatalog.html">Plugin Catalog</a> + </p> + <form id="addPluginForm"> + <p id="tagline" style="font-style: italic;"></p> + <p id="pPreviewImage" style="text-align: center; margin: 2em 0;"></p> + + <p id="overview"></p> + + <div data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em;" data-theme="a"> + <h3>Install</h3> + <p id="pCurrentVersion"> + </p> + <p> + <label for="selectVersion">Select version to install:</label> + <select id="selectVersion" name="selectVersion"></select> + </p> + + <p> + <button id="btnInstall" type="submit" data-icon="download" data-theme="b">Install</button> + </p> + </div> + </form> + + <form name="_xclick" target="_blank" action="https://www.paypal.com/cgi-bin/webscr" method="post"> + <div class="premiumPackage" data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em; display: none" data-theme="a"> + <h3>Registration</h3> + <p id="regStatus"> + </p> + <p id="regInfo"> + </p> + <p id="regPrice"> + </p> + <input type="hidden" name="cmd" value="_xclick"> + <input type="hidden" id="payPalEmail" name="business" value="mb_1358534950_biz@reedsplace.com"> + <input type="hidden" name="currency_code" value="USD"> + <input type="hidden" id="featureName" name="item_name" value="MBSupporter"> + <input type="hidden" id="amount" name="amount" value="10"> + <input type="hidden" id="featureId" name="item_number" value="MBSupporter"> + <input type="hidden" name="notify_url" value="http://mb3admin.com/admin/service/services/ppipn.php"> + <input type="hidden" name="return" id ="paypalReturnUrl" value="#"> + <a data-role="button" id="ppButton" onclick="_xclick.submit();"><img src="css/images/registerpp.png"/></a> + <p id="noEmail" style="display: none"><strong>This developer has not provided a PayPal email. Please see their + website for registration information.</strong> + </p> + + </div> + + <div data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em;" data-theme="a"> + <h3>Developer Info</h3> + <p id="developer"></p> + <p id="pViewWebsite" style="display: none;"> + <a href="#" data-rel="external" target="_blank">View Website</a> + </p> + </div> + + <div data-role="collapsible" data-content-theme="c" style="margin-top: 2em;" data-theme="a"> + <h3>Revision History</h3> + <div id="revisionHistory"></div> + </div> + </form> + + </div> + </div> + <script type="text/javascript"> + $('#addPluginForm').on('submit', AddPluginPage.onSubmit); + </script> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/advanced.html b/MediaBrowser.WebDashboard/Html/advanced.html new file mode 100644 index 0000000000..d9a7f78cc9 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/advanced.html @@ -0,0 +1,56 @@ +<!DOCTYPE html> +<html> +<head> + <title>Advanced</title> +</head> +<body> + <div id="advancedConfigurationPage" data-role="page" class="page type-interior"> + + <div data-role="content"> + <div class="content-primary"> + <form id="advancedConfigurationForm"> + + <ul data-role="listview" class="ulForm"> + <li> + <input type="checkbox" id="chkRunAtStartup" name="chkRunAtStartup" /> + <label for="chkRunAtStartup">Run server at startup</label> + </li> + <li> + <label for="txtPortNumber">Http server port number: </label> + <input type="number" id="txtPortNumber" name="txtPortNumber" pattern="[0-9]*" required="required" min="1" /> + </li> + <li id="fldWebSocketPortNumber" style="display:none;"> + <label for="txtWebSocketPortNumber">Web socket port number: </label> + <input type="number" id="txtWebSocketPortNumber" name="txtWebSocketPortNumber" pattern="[0-9]*" required="required" min="1" /> + </li> + <li> + <input type="checkbox" id="chkEnableDeveloperTools" name="chkEnableDeveloperTools" /> + <label for="chkEnableDeveloperTools">Enable developer tools</label> + <div class="fieldDescription"> + When enabled, developer tools will be available from the system tray. + </div> + </li> + <li> + <input type="checkbox" id="chkDebugLog" name="chkDebugLog" /> + <label for="chkDebugLog">Enable debug logging </label> + </li> + <li> + <button type="submit" data-theme="b" data-icon="ok"> + Save + </button> + <button type="button" onclick="Dashboard.navigate('dashboard.html');" data-icon="delete"> + Cancel + </button> + </li> + </ul> + + </form> + </div> + </div> + + <script type="text/javascript"> + $('#advancedConfigurationForm').on('submit', AdvancedConfigurationPage.onSubmit); + </script> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/advancedMetadata.html b/MediaBrowser.WebDashboard/Html/advancedMetadata.html new file mode 100644 index 0000000000..60e02ba3c0 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/advancedMetadata.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html> +<head> + <title>Metadata</title> +</head> +<body> + <div id="advancedMetadataConfigurationPage" data-role="page" class="page type-interior"> + + <div data-role="content"> + + <div class="content-primary"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> + <a href="metadata.html" data-role="button">Basics</a> + <a href="metadataImages.html" data-role="button">Images</a> + <a href="advancedMetadata.html" data-role="button" class="ui-btn-active">Advanced</a> + </div> + + <form id="advancedMetadataConfigurationForm"> + <ul data-role="listview" class="ulForm"> + <li> + <label>Disable internet providers for:</label> + <div id="divItemTypes"></div> + </li> + <li> + <button type="submit" data-theme="b"> + Save + </button> + <button type="button" onclick="Dashboard.navigate('dashboard.html');"> + Cancel + </button> + </li> + </ul> + </form> + </div> + + </div> + + <script type="text/javascript"> + $('#advancedMetadataConfigurationForm').on('submit', AdvancedMetadataConfigurationPage.onSubmit); + </script> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/css/images/bg.png b/MediaBrowser.WebDashboard/Html/css/images/bg.png Binary files differnew file mode 100644 index 0000000000..d1e8358715 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/bg.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/checkMarkGreen.png b/MediaBrowser.WebDashboard/Html/css/images/checkMarkGreen.png Binary files differnew file mode 100644 index 0000000000..c5cd1c7d4c --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/checkMarkGreen.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/checkmarkblack.png b/MediaBrowser.WebDashboard/Html/css/images/checkmarkblack.png Binary files differnew file mode 100644 index 0000000000..d825a1d761 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/checkmarkblack.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/clients/android.png b/MediaBrowser.WebDashboard/Html/css/images/clients/android.png Binary files differnew file mode 100644 index 0000000000..88e3b93e4f --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/clients/android.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/clients/html5.png b/MediaBrowser.WebDashboard/Html/css/images/clients/html5.png Binary files differnew file mode 100644 index 0000000000..2fdbe426ad --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/clients/html5.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/clients/ios.png b/MediaBrowser.WebDashboard/Html/css/images/clients/ios.png Binary files differnew file mode 100644 index 0000000000..1429af5dc9 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/clients/ios.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/clients/mb.png b/MediaBrowser.WebDashboard/Html/css/images/clients/mb.png Binary files differnew file mode 100644 index 0000000000..c641c0652c --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/clients/mb.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/clients/win8.png b/MediaBrowser.WebDashboard/Html/css/images/clients/win8.png Binary files differnew file mode 100644 index 0000000000..7ee409ff82 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/clients/win8.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/clients/windowsphone.png b/MediaBrowser.WebDashboard/Html/css/images/clients/windowsphone.png Binary files differnew file mode 100644 index 0000000000..1a31e55f61 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/clients/windowsphone.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/clients/windowsrt.png b/MediaBrowser.WebDashboard/Html/css/images/clients/windowsrt.png Binary files differnew file mode 100644 index 0000000000..6a91da5e62 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/clients/windowsrt.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/cloudNetwork.png b/MediaBrowser.WebDashboard/Html/css/images/cloudNetwork.png Binary files differnew file mode 100644 index 0000000000..2f917c1a0b --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/cloudNetwork.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/currentUserDefaultBlack.png b/MediaBrowser.WebDashboard/Html/css/images/currentUserDefaultBlack.png Binary files differnew file mode 100644 index 0000000000..fff3f51a23 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/currentUserDefaultBlack.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/currentUserDefaultWhite.png b/MediaBrowser.WebDashboard/Html/css/images/currentUserDefaultWhite.png Binary files differnew file mode 100644 index 0000000000..acfa26e9de --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/currentUserDefaultWhite.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/defaultCollectionImage.png b/MediaBrowser.WebDashboard/Html/css/images/defaultCollectionImage.png Binary files differnew file mode 100644 index 0000000000..d1e862a694 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/defaultCollectionImage.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/donatepp.png b/MediaBrowser.WebDashboard/Html/css/images/donatepp.png Binary files differnew file mode 100644 index 0000000000..c99d2ea135 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/donatepp.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/home.png b/MediaBrowser.WebDashboard/Html/css/images/home.png Binary files differnew file mode 100644 index 0000000000..216608e42c --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/home.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/iossplash.png b/MediaBrowser.WebDashboard/Html/css/images/iossplash.png Binary files differnew file mode 100644 index 0000000000..6467ebe7d3 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/iossplash.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/itemDetails/audioDefault.png b/MediaBrowser.WebDashboard/Html/css/images/itemDetails/audioDefault.png Binary files differnew file mode 100644 index 0000000000..4e59c995ed --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/itemDetails/audioDefault.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/itemDetails/gameDefault.png b/MediaBrowser.WebDashboard/Html/css/images/itemDetails/gameDefault.png Binary files differnew file mode 100644 index 0000000000..b08ade6e4a --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/itemDetails/gameDefault.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/itemDetails/videoDefault.png b/MediaBrowser.WebDashboard/Html/css/images/itemDetails/videoDefault.png Binary files differnew file mode 100644 index 0000000000..b315bdf1ae --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/itemDetails/videoDefault.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/leftArrowBlack.png b/MediaBrowser.WebDashboard/Html/css/images/leftArrowBlack.png Binary files differnew file mode 100644 index 0000000000..91e4a2571e --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/leftArrowBlack.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/leftArrowWhite.png b/MediaBrowser.WebDashboard/Html/css/images/leftArrowWhite.png Binary files differnew file mode 100644 index 0000000000..9f3140b17f --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/leftArrowWhite.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/logindefault.png b/MediaBrowser.WebDashboard/Html/css/images/logindefault.png Binary files differnew file mode 100644 index 0000000000..9e7311e4fc --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/logindefault.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/mblogoblackfull.png b/MediaBrowser.WebDashboard/Html/css/images/mblogoblackfull.png Binary files differnew file mode 100644 index 0000000000..340f12d9df --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/mblogoblackfull.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/mblogowhitefull.png b/MediaBrowser.WebDashboard/Html/css/images/mblogowhitefull.png Binary files differnew file mode 100644 index 0000000000..48c8f72d39 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/mblogowhitefull.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/media/nextTrack.png b/MediaBrowser.WebDashboard/Html/css/images/media/nextTrack.png Binary files differnew file mode 100644 index 0000000000..173734fe00 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/media/nextTrack.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/media/pause.png b/MediaBrowser.WebDashboard/Html/css/images/media/pause.png Binary files differnew file mode 100644 index 0000000000..1f347cdef9 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/media/pause.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/media/play.png b/MediaBrowser.WebDashboard/Html/css/images/media/play.png Binary files differnew file mode 100644 index 0000000000..0a0529f2f7 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/media/play.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/media/playCircle.png b/MediaBrowser.WebDashboard/Html/css/images/media/playCircle.png Binary files differnew file mode 100644 index 0000000000..6d2ffd3413 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/media/playCircle.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/media/previousTrack.png b/MediaBrowser.WebDashboard/Html/css/images/media/previousTrack.png Binary files differnew file mode 100644 index 0000000000..f5b47417f2 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/media/previousTrack.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/media/stop.png b/MediaBrowser.WebDashboard/Html/css/images/media/stop.png Binary files differnew file mode 100644 index 0000000000..ea6bcb96e3 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/media/stop.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/movieFolder.png b/MediaBrowser.WebDashboard/Html/css/images/movieFolder.png Binary files differnew file mode 100644 index 0000000000..ac52cab359 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/movieFolder.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/notifications/cancelled.png b/MediaBrowser.WebDashboard/Html/css/images/notifications/cancelled.png Binary files differnew file mode 100644 index 0000000000..319fd7faba --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/notifications/cancelled.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/notifications/done.png b/MediaBrowser.WebDashboard/Html/css/images/notifications/done.png Binary files differnew file mode 100644 index 0000000000..b64e558cde --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/notifications/done.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/notifications/download.png b/MediaBrowser.WebDashboard/Html/css/images/notifications/download.png Binary files differnew file mode 100644 index 0000000000..780f72dcb1 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/notifications/download.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/notifications/error.png b/MediaBrowser.WebDashboard/Html/css/images/notifications/error.png Binary files differnew file mode 100644 index 0000000000..c6b5693c4e --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/notifications/error.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/notifications/info.png b/MediaBrowser.WebDashboard/Html/css/images/notifications/info.png Binary files differnew file mode 100644 index 0000000000..fb724718fd --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/notifications/info.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/premiumflag.png b/MediaBrowser.WebDashboard/Html/css/images/premiumflag.png Binary files differnew file mode 100644 index 0000000000..e34fe810e5 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/premiumflag.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/registerpp.png b/MediaBrowser.WebDashboard/Html/css/images/registerpp.png Binary files differnew file mode 100644 index 0000000000..e5ecaa8639 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/registerpp.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/rightArrow.png b/MediaBrowser.WebDashboard/Html/css/images/rightArrow.png Binary files differnew file mode 100644 index 0000000000..f5771d4199 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/rightArrow.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/stars.png b/MediaBrowser.WebDashboard/Html/css/images/stars.png Binary files differnew file mode 100644 index 0000000000..4a31313f09 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/stars.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/suppbadge.png b/MediaBrowser.WebDashboard/Html/css/images/suppbadge.png Binary files differnew file mode 100644 index 0000000000..9295ae07dc --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/suppbadge.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/toolsBlack.png b/MediaBrowser.WebDashboard/Html/css/images/toolsBlack.png Binary files differnew file mode 100644 index 0000000000..233e7ea17b --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/toolsBlack.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/toolsWhite.png b/MediaBrowser.WebDashboard/Html/css/images/toolsWhite.png Binary files differnew file mode 100644 index 0000000000..c55c16766e --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/toolsWhite.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/touchicon.png b/MediaBrowser.WebDashboard/Html/css/images/touchicon.png Binary files differnew file mode 100644 index 0000000000..c476cbb35c --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/touchicon.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/touchicon114.png b/MediaBrowser.WebDashboard/Html/css/images/touchicon114.png Binary files differnew file mode 100644 index 0000000000..7099b59705 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/touchicon114.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/touchicon72.png b/MediaBrowser.WebDashboard/Html/css/images/touchicon72.png Binary files differnew file mode 100644 index 0000000000..6802032703 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/touchicon72.png diff --git a/MediaBrowser.WebDashboard/Html/css/images/userFlyoutDefault.png b/MediaBrowser.WebDashboard/Html/css/images/userFlyoutDefault.png Binary files differnew file mode 100644 index 0000000000..f27a4bcb34 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/images/userFlyoutDefault.png diff --git a/MediaBrowser.WebDashboard/Html/css/site.css b/MediaBrowser.WebDashboard/Html/css/site.css new file mode 100644 index 0000000000..c9b2089c73 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/css/site.css @@ -0,0 +1,897 @@ +@font-face { + font-family: "Open Sans"; + font-style: normal; + font-weight: 700; + src: local("Open Sans Bold"), local("OpenSans-Bold"), url(http://themes.googleusercontent.com/static/fonts/opensans/v6/k3k702ZOKiLJc3WVjuplzJ1r3JsPcQLi8jytr04NNhU.woff) format('woff'); +} + +@font-face { + font-family: "Open Sans"; + font-style: normal; + font-weight: 300; + src: local("Open Sans Light"), local("OpenSans-Light"), url(http://themes.googleusercontent.com/static/fonts/opensans/v6/DXI1ORHCpsQm3Vp6mXoaTZ1r3JsPcQLi8jytr04NNhU.woff) format('woff'); +} + +@font-face { + font-family: "Open Sans"; + font-style: normal; + font-weight: 800; + src: local("Open Sans Extrabold"), local("OpenSans-Extrabold"), url(http://themes.googleusercontent.com/static/fonts/opensans/v6/EInbV5DfGHOiMmvb1Xr-hp1r3JsPcQLi8jytr04NNhU.woff) format('woff'); +} + +@font-face { + font-family: "Open Sans"; + font-style: normal; + font-weight: 400; + src: local("Open Sans"), local("OpenSans"), url(http://themes.googleusercontent.com/static/fonts/opensans/v6/K88pR3goAWT7BTt32Z01mz8E0i7KZn-EPnyo3HZu7kw.woff) format('woff'); +} + +body { + overflow-y: scroll!important; +} + +h1 { + font-family: 'Segoe UI Light', 'Open Sans', Arial, Helvetica, sans-serif; + font-weight: 200; + font-size: 32pt; +} + +.toolsSidebar h1 { + font-size: 42pt; +} + +.ui-loader h1 { + font-weight: bold; + font-family: Arial; +} + +h2 { + font-family: 'Segoe UI Semiight', 'Open Sans', Arial, Helvetica, sans-serif; + font-weight: 400; + font-size: 22pt; +} + +pre, textarea.pre { + display: block; + padding: 8.5px; + font-size: 12.025px; + line-height: 18px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + color: #000; +} + +.type-interior h2 { + color: #1B58B8; +} + +/* + Page / Base styles + */ +.page { + background: #f2f2f2; + background-attachment: fixed; +} + +.libraryPage { + background: #1d1d1d url(images/bg.png) top left repeat-x; + background: #262626!important; + background-attachment: fixed!important; +} + + .libraryPage .interiorLink { + color: #2489ce; + font-weight: bold; + } + +/* + Header + */ +.header { + padding: 10px 0 10px 10px; +} + +.imgLogo { + height: 45px; +} + + +.ui-popup-container { + z-index: 99999; +} + +.headerButtons { + float: right; + position: absolute; + top: 10px; + right: 10px; +} + +.header .imageLink { + display: inline-block; +} + +.imageLink + .imageLink { + margin-left: 30px; +} + +.header .imageLink img { + height: 32px; + vertical-align: middle; +} + +.btnCurrentUser { + text-decoration: none; +} + +.currentUsername { + margin-right: 7px; + font-size: 20px; + color: #000; + position: relative; + top: 4px; +} + +.libraryPage .currentUsername { + color: #fff; +} + +h1 .imageLink { + margin-left: 15px; +} + + h1 .imageLink img { + height: 32px; + } + +.imageLink:hover { + opacity: .5; +} + +.type-home h1 { + margin-top: 1.25em; + margin-bottom: 10px; + padding-bottom: 5px; + font-weight: normal; + border-bottom: 1px solid #777; +} + +.libraryPage .ui-content > h1:first-child { + margin-top: 0; +} + +.pageTitle { + margin-top: 0; +} + +.imageButton { + background: transparent; + border: 0; + padding: 0; + cursor: pointer; + cursor: hand; +} + + .imageButton:hover { + opacity: .5; + } + + .imageButton[disabled], .imageButton[disabled]:hover { + opacity: .3!important; + cursor: default; + } + +/* + Forms + */ +form, .readOnlyContent { + max-width: 600px; +} + +.fieldDescription { + font-size: 11px; + padding-left: 5px; +} + +.ulForm { + margin-bottom: 20px!important; +} + + .ulForm li:not(.ui-li-divider) { + background: none; + border-top: none; + border-bottom: none; + } + +.popup .ulForm { + margin-bottom: 0!important; +} + +.popup .ui-content { + padding: 20px; +} + +.content-secondary { + z-index: 99996; + background: #262626; + border: 0; + margin-top: 40px; +} + + .content-secondary h1 { + margin: 0; + padding: 20px 0 20px 30px; + color: #fff; + } + +.sidebarLinks a { + display: block; + padding: 12px 15px 12px 30px; + text-decoration: none; + color: #fff!important; + text-shadow: none!important; + font-weight: normal!important; + font-size: 17px; +} + + .sidebarLinks a:hover { + background: #f2f2f2; + color: #000!important; + } + + .sidebarLinks a.selectedSidebarLink { + background: #2572EB!important; + color: #fff!important; + } + +/* Tabs (e.g. advanced metadata page) */ +.localnav { + margin-bottom: 40px!important; +} + + .localnav + form { + margin-top: -10px; + } + +.page > .ui-content { + padding-bottom: 100px; +} + +@media all and (min-width: 650px) { + + .imgLogo { + height: 60px; + } + + .header { + padding-left: 30px; + padding-top: 20px; + padding-bottom: 15px; + } + + .headerButtons { + top: 20px; + right: 30px; + } + + .localnav .ui-btn-inner { + font-size: 16px; + } + + .libraryPage .ui-content { + padding-right: 50px; + padding-left: 50px; + } + + .type-interior > .ui-content { + padding-right: 0; + padding-left: 0; + padding-top: 0; + overflow: hidden; + } + + .content-secondary { + text-align: left; + width: 45%; + position: fixed; + top: 0; + left: 0; + bottom: 0; + margin: 0; + } + + .content-primary { + width: 45%; + float: right; + padding: 0 6% 3em 0; + margin: 0; + } + + .content-primary ul:first-child { + margin-top: 0; + } +} + +@media all and (min-width: 750px) { + + .content-secondary { + width: 34%; + } + + .content-primary { + width: 56%; + } +} + +@media all and (min-width: 1200px) { + + + .content-secondary { + width: 30%; + } + + .content-primary { + width: 60%; + } +} + +@media all and (min-width: 1440px) { + + + .content-secondary { + width: 25%; + } + + .content-primary { + width: 65%; + } +} + +@media all and (min-width: 1920px) { + + + .content-secondary { + width: 20%; + } + + .content-primary { + width: 70%; + } +} + +/* + Media Library Page + */ +.mediaFolderButtons { + margin-top: 10px; +} + +.mediaFolderLocations { + margin: 1em .25em!important; +} + +.mediaLocationsHeader { + padding-top: .75em!important; + padding-bottom: .75em!important; +} + + .mediaLocationsHeader .ui-btn { + position: absolute; + right: 3px; + margin-top: 0!important; + margin-bottom: 0!important; + top: 6px; + } + +#divVirtualFolders .ui-btn-inner, .mediaLocationsHeader, #divVirtualFolders .ui-btn-text { + font-size: 14px; +} + +#ulDirectoryPickerList a { + padding-top: .4em; + padding-bottom: .4em; + font-size: 15px; +} + +/* + Plugin updates Page + */ +#pluginUpdatesForm table { + width: 100%; +} + +#pluginUpdatesForm td + td { + text-align: center; +} + + +/* + List Vew Items + */ + +.posterViewItem { + display: inline-block; + margin: 5px; + text-align: center; + font-size: 15px; + padding: 0; + position: relative; + padding-bottom: 28px; +} + + .posterViewItem a { + color: white!important; + font-weight: normal!important; + text-decoration: none; + } + + .posterViewItem img { + max-width: 155px; + max-height: 148px; + vertical-align: bottom; + } + +.premiumBanner img { + position: absolute; + text-align: right; + top: 0; + right: 0; + width: 75px!important; + height: 75px!important; + max-width: 75px!important; + max-height: 75px!important; +} + +.posterViewItemText { + text-overflow: ellipsis; + overflow: hidden; + text-wrap: none; + white-space: nowrap; + margin: 0; + padding: 4px 2px 0; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 24px; + background: #181818; + text-shadow: none; +} + +.posterViewItem:hover, .userItem:hover { + -moz-box-shadow: 0 0 20px 3px #2572EB; + -webkit-box-shadow: 0 0 20px 3px #2572EB; + box-shadow: 0 0 20px 3px #2572EB; +} + +@media all and (min-width: 750px) { + + .posterViewItem { + font-size: 16px; + padding-bottom: 29px; + } + + .posterViewItemText { + padding-top: 5px; + } + + .posterViewItem img { + max-width: 190px; + max-height: 190px; + } +} + +@media all and (min-width: 1200px) { + + .posterViewItem { + font-size: 17px; + } + + .posterViewItem img { + max-width: 280px; + max-height: 250px; + } +} + +@media all and (min-width: 1920px) { + + .posterViewItem { + font-size: 19px; + padding-bottom: 33px; + } + + .posterViewItemText { + height: 28px; + } + + .posterViewItem img { + max-width: 352px; + max-height: 300px; + } +} + +.userItem { + display: inline-block; + margin: 5px; + font-size: 15px; + text-align: left; +} + +.userItemImage { + height: 100px; + width: 100px; + vertical-align: bottom; +} + +.userItemContent { + display: inline-block; + height: 100px; + width: 180px; + float: right; + text-shadow: none; + font-family: 'Segoe UI Light', 'Open Sans', Arial; +} + +.userItemContentInner { + padding: 15px 5px 5px 10px; + color: #fff; +} + +.userItemHeader { + margin: 0 0 10px; + font-size: 16px; + text-overflow: ellipsis; + overflow: hidden; + text-wrap: avoid; + font-family: 'Segoe UI Semilight', 'Open Sans', Arial; +} + +@media all and (min-width: 750px) { + + .userItem { + font-size: 16px; + } + + .userItemContentInner { + padding: 30px 20px 20px; + } + + .userItemImage { + height: 140px; + width: 140px; + } + + .userItemContent { + height: 140px; + width: 210px; + } + + .userItemHeader { + font-size: 26px; + } +} + +@media all and (min-width: 1200px) { + + .userItem { + font-size: 18px; + } + + .userItemImage { + height: 180px; + width: 180px; + } + + .userItemContent { + height: 180px; + width: 270px; + } + + .userItemHeader { + font-size: 32px; + } +} + +@media all and (min-width: 1920px) { + + .userItem { + font-size: 20px; + } + + .userItemImage { + height: 240px; + width: 240px; + } + + .userItemContent { + height: 240px; + width: 360px; + } + + .userItemHeader { + font-size: 40px; + } +} + +/* Startup wizard */ +.wizardPage { + background: #e2e2e2; +} + +.wizardContent { + max-width: 800px; + padding: .5em 2em 1em; + margin: 0 auto; + background: #f2f2f2; +} + +.wizardNavigation { + text-align: right; +} + +.wizardContent form { + max-width: 100%; +} + +.wizardContent p { + margin: 2em 0; +} + +.wizardContent h2 img { + height: 35px; + vertical-align: middle; + margin-right: .5em; + position: relative; + top: -3px; +} + +/* User Image */ +.imageDropZone { + border: 2px dashed #bbb; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + padding: 25px; + text-align: center; + color: #bbb; +} + +/* Dashboard home */ +.tblConnections td { + padding: .5em 0 .5em 1.25em; +} + + .tblConnections td:first-child { + padding-left: 0; + } + +.tblConnections img { + height: 50px; +} + +.clientNowPlayingImage { + border-radius: 5px; + border: 2px solid #ccc; +} + +/* Footer */ +#footer { + background: #5a5a5a; + position: fixed; + bottom: -2px; + left: -2px; + right: -2px; + z-index: 99997; +} + +.footerNotification { + text-shadow: none; + padding: .5em 1em; + margin: 0; + font-weight: normal; + border-top: 1px solid #999; +} + +.notificationIcon { + height: 24px; + margin-right: 1em; + vertical-align: middle; +} + +/* + * Gradient Shadow + */ + +/* All HTML5 progress enabled browsers */ +progress { + /* Turns off styling - not usually needed, but good to know. */ + appearance: none; + -moz-appearance: none; + -webkit-appearance: none; + /* gets rid of default border in Firefox and Opera. */ + border: solid #cccccc 2px; + border-radius: 4px; + margin: 0; +} + + /* Polyfill */ + progress[role]:after { + background-image: none; /* removes default background from polyfill */ + } + +/* + * Background of the progress bar background + */ + +/* Firefox and Polyfill */ +progress { + background: #cccccc !important; /* !important only needed in polyfill */ +} + + /* Chrome */ + progress::-webkit-progress-bar { + background: #cccccc; + } + + /* + * Background of the progress bar value + */ + + /* Firefox */ + progress::-moz-progress-bar { + border-radius: 5px; + background-image: -moz-linear-gradient( center bottom, rgb(43,194,83) 37%, rgb(84,240,84) 69% ); + } + + /* Chrome */ + progress::-webkit-progress-value { + border-radius: 5px; + background-image: -webkit-gradient( linear, left bottom, left top, color-stop(0, rgb(43,194,83)), color-stop(1, rgb(84,240,84)) ); + background-image: -webkit-linear-gradient( center bottom, rgb(43,194,83) 37%, rgb(84,240,84) 69% ); + } + + /* Polyfill */ + progress[aria-valuenow]:before { + border-radius: 5px; + background-image: -moz-linear-gradient( center bottom, rgb(43,194,83) 37%, rgb(84,240,84) 69% ); + background-image: -ms-linear-gradient( center bottom, rgb(43,194,83) 37%, rgb(84,240,84) 69% ); + background-image: -o-linear-gradient( center bottom, rgb(43,194,83) 37%, rgb(84,240,84) 69% ); + } + +/* Detail Page*/ + +.itemDetailImage { + max-width: 100%; + max-height: 400px; +} + +.itemImageBlock { + vertical-align: top; +} + +.itemDetailBlock { + vertical-align: top; + padding-top: 1em; +} + + .itemDetailBlock p { + margin-top: 0; + } + +.starRating { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMYAAAA6CAYAAADryyY/AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAS+klEQVR4Xu1de1gUV54dMJmdyWRcZzWZPNZMRLIRgxhFRhOdRCRKwMQkoGZ0hCCiGOOqSdSwrpmMiE58JDOT6LpmvnE0Jk40RoOPaHjKU1QQEBB5qPgCROhmdP377vnRVVDdXe/qruqgfN/5qrpuFV333HN+t+6jbv+IMfaju7jLwV0NOGugyxRW/rVdSe2H7/fn4GfVvdzlwcG81TzU19f7hB6sJsLP1pK2qvXSqjSUyU+BewBLzGGxILp4OHfu3B3Pw/nz532CB0uNcbl+ZUBnaxqzt6zunB0XNgSm+DnQx4paw0pj8DxAFJ0zZsy4Y3morKwMuHDhAvMFHqw0hp+tedWOztZURqgue/dzGOLfuZrD9FrDQmN080CiKCwsvGN5aGxs3EEc+AIPlhnj8rmU0M6WVawLzX/owptJY6JgjAeAe81+pLLKGEIeECkpWrKEhIQ7joeKiopQ3hS+wINVxvC3Xf19XmfzBzAEh2sfsOqTSw7DEIHA/Vxj3LSnKouM4cQDCQJRk+Xn599xPDQ0NOTxhvAFHqwwht+1+vciOq/9nnXh6vtO2PrJq0lww0PAj01zhTW9MW48QByMx8aNG+8YHs6cORNBAYEg5ID2reLBCmP426+sbOq8uhKGcMfF6nfLoNMnuYY4deOa8mdBjeHGg1AUpaWldwwP6KJtcjUE/9kqHsw2hl9Lw/I5nVf+mzljBT73YOdnMcvghoFcrWFKQ9xkY4jyAIEwITZt2tTreaiqqprjagpf4MFUYxRnJvW3X0pp6rz8X0wcKTiewlrrl7bAFMFAX7O6b800hhQProLAI0av5uHQoUP96+rqmlzz7Qs8mGkMvxuNy1I7L0H8l96TwXKkLWfpu15fBVM8AvyLGT1UJhpDkgeIhLli+/btvZaH6urqVLE8+wIPphnjVM6c/vamZZ2dTRB+N5Zh3wGk9eDiMtbe+O7NyIjBYTBFPzNqDbOMIccDRr6ZELW1tQziuTl+/Phex8ORI0f6I6+drnkW+2wFD2YZw6+98Z2/2C8uZe54F8c4XMBWgJKMhK3coN9PvF1rmGQMWR5IAISzZ8864eDBg72OBxj+L3x+pbZW8mCKMS6ULwhwCP4dcZzH8S687YQb9YtvvfD842Ngil8ANI/Ka39mGEOJB1ch8J/R1rg1bty4XsPD8ePHA6TyKnfcTB7MMIZ/R8Pi9B7RL4H4lbAY5zhQXZh4CG4YDHh10M8EYyjyUFNTw6SQnZ3da3hAbZHOG0Auz2JpZvHgbWP4XateEMGL3H27iNkbpfCfSHNgXnzIZBjjl97svvWyMVTxoCSSmTNn/uB5wLhEhFI+ldLN4MHbxvDvqF+YxwvcadsA0XdjIfalcbE0iQa7/sObg35eNoYqHhBJqbEtiaKioh88Dxi3yBMTvlLehelm8OANY9CAHMH/amVyrLPg32L2eiksQJoE6haw//lwwjyu+5Ya4jQizn+PR9odXjCGZh4gGiYHPGOztLS0HywPJ0+ejHU1gFKexdLN4EGvMboLnRMpvUNxT/Wx+MBLpUkvNFfOS2qtSk7rOPfmpW6xQ9z2bryJfSXMxzk9uFKWWF+eOePTs/mz3qrNj4ssTJ9K00ZojINm4lLDnO5B+CagphFzncbwKA9U4EpAw7X+8OHDn2ZlZb0FRO7du9dnecjIyAgsLi5+4dSpU0l4hErD+xaXeKEr5VMp3ds8yBlDWOgkuj7Ze2MHXDmdFHG1PCm2rTo5Ffi0o3Z+nu3c/CZxoTuL234On7uRjH0VqJ3H7DJor046c6NqTn5L+ezNzeWz0y4Ux01vLJo1EfdLNQtNRCTjdN2/S03jZBwZY5jGA4TD9OL06dNnysrK8k+cOLEZSMvLy5uem5vrVR527do1oKSkJALfF4vvTwU+xfTxPOShSUnYrul68+16nad4EBqDou29tYXxYfXFb0y6VpG0tLkiaU372eT8GzXzCoTRW7PAFcRtr50L8cvgbBKzy2IO0sVxvSKhsK0yoeDyyVl/bCr53XsVGVOjThyMeQZ5/RlnHjKOv8AYlvGgJA6IjukFHmMKEbkL8CLUHzGt/T1Mx4jat2+fIg85OTlhx44dmwTxL8X/WFNeXp4P8RVICV8pD55I18sBXaeWhy5jtFXNHYHobVeM4EYErihuEr+0wO1nE5Eughoc68Zs7MshAek9aKuIr9rxp/DhZBBf4MFIgUOwTC8glqoNGzZ084CaZwQEbPeEiKX+h5G8yl2rlwO6TsgDX2P0qcicEdVRM/efjscW70RvSXGT4A0I3F4NsXfjDewroCqe3aiIu/XB2yNnwhSPA325GsNSHqjAjRQsIjnTCojh1qJFi9x4+O6776JwL/9UMocvClwrB3S+Kw+8Mejx4f6t68ZPbq9KvOl4bPF29KbI7hzB9QjcDpFLIw5p7jhfOL1p/qwhi5Dn0cCvKO+cMSzlgTeFnoKVuwY1ABMDHpOasPiCJA9r1qyZjOtu6hW/EZPTtVbywBuDGpj0rD3gxfEDw66VxtXpfTzRLG6K7rLiJuGLC9xxfJYyzvyO2TmcL5jWFBTYLw55HQ88AdB0k3s5Y1jKg5IQpASu5ziZYvDgwYo8PPfcc2HoWarTK3KlPOlJ15NfueAgxoOw8U2ioO7P/pMjHgu9VDKzVOvjiZ7o3SN6bQLnhS67rZzJ7AIUfxOdNzSw3yzk8XmAujn7cQHBT9D4towHTxa48H+hq5QJsXv37jyIQTUP4eHhoWiwl+oRsdQ13sqr3P/VwoNrdy2JgsYEaF7SwPq86fvdxW4welOEF0RwVfsuAheKXWzfVjmDdaMC+8DxfdG5yFM0QFO46fHJaQ0rl+5aS3hQEotrwSp9Ri8Uc8WePXt084Bxk/2uQle6Z2+kK+XbNV0PD1LjGNTnT92Zj5YdfmWT6OOKVnHT+R4QOIm8B7/FvgTKX2c2Dp+tHbMJeXkRGAnQ2lVkfKeF3STGMUzlQarAxQpW7TE0Kqlh2YXVq1cb5uHbb7/d5Cmxe0Lg3uJBboCPRHEf8MjRzyet7I7sGsVNZhCL4HoEzgvdfTsdJnBH68mptz9bM5rEQANd1B35MJcnt9UOZQb4TONBrpCFAte6j7lFt1NTUz3Gw7Zt21by5tAqbjpfrZjFztOad+H5WnhQmhJCvTS0puyjf1s/dvaN07+92SVyp6jNf5aJ3hTVBRFcq8B7RD+N2U5LYSrSenD9RMzt2VMDaDGBSQC9P/4glxfRlUcUpoSYwoOWQseAG1MDEkNMTNfiEh7lYe3atbPx/Tf1ilxLXuXOVcMBnaOVByVjgM+u+Udkjl9uWBEac6Ns+k15kYtHb+eIrl7gQrH37MfCBBzKsHVBY85LTYnTApZyNcUwbAcA1LEguRyPirlSXudBbSGLnYepGcwV33//fVNsbKzXeFi+fHkMvvOmJ0RuJO/Caz3Fgxpj8OaguUcPvDMnaMLV4pg6W7mcuCnNOYLrEbitLAail8JrSONQii2HxuzJTUGD+8bjXicAT9E9AzRnSnZSoQpjeJ0HKmCxgtVzjEwREBDgdR6wnOgEzMuqI3N4Sty+wINaY5Ao+D7+vlOjHhvWfPy1WofYBdGb9kUiuB6B80K3lb4K0UvhFaT1oHjPhNynnuj7Ou6V5gANAv4VULUOrkpjeJUHPQagazDT1AmY3JcbGBhoGg+RkZHD0J1bq7Ym05tPpes8yYMWY/Ci4Ltzf3X2aHR6j+jFI7gegQvF3rM/BSbgcApbFxTvDnfthqQ1qVT/3oYGY3iNB9eC1fP5yy+/tIwHTExMVxKvmnQ9+Xa9xigPWo1BoqA/6qmhLs/HKw9O2tkT0Z0juB6B2069DNFL4ORLzCaCLzeG7cC9vAS4dseqfidDozG8woNaQWAkmolh3bp1lvOwf//+nbz41eZH73ne5EGvMYTmeKyl+KVm1wiuXeCTIXoxRDPbCTFE4XgUa8yIaMLNvArQvCdaoI26mDX/+IxOY3iUB6mC5o+jZ4V6V0SBSX8+wwPaHM1axK6Ub9d0M3gwYowuUaQuChroHMX1CZxE7o4XcYxDCbaiiKQfEaTBO5riQYOSmk1BGTFgDI/xIFfgfBrep6AflxGFL/CwcOHCgWqFria/Uud4mwejgvCrOxIxyRHRxYTNH1MncFtJJMQvhUlIE8faJU++DVHQEju6l/M0aAyP8CBX2GrSMH3cch6wONwkLYJXky+t53iCB6PG8G/Jn5jmHMnlxE1p0gK3lUxEOofj2HbjBey7IgLHHNj5YcgGmCKIe4xS3a7gGwoeqDE8woOYAAoKCphaYJq45Txg1m6aViGrOV8tB3SeJ3gwaow+bUUTD7iLXUzgYuKmYz0C79ov5jEB+1IIRxqHonBWsCNsP8RNUz5oYqCu39QwWGN4hAexwkc3KP3CkipgqoblPKB9cUBO6FoELjxXLQd0nid4MGqMe9qLIiod0dy4wG0QuTvG45gcnmd1B589A0PQrFl6t8KKNoZHeNBS+K7nQpAME/ws5wH3USknfiN5VHOtp3gwaowfO6K6cwTXK3Bb4fNMHM/huDxgiLEAjXLrWuPWYI3hER6o4KlgjcBqHtSIV805Rjiga43yYMQYfo3fjZ3oHs2lxE3HlQVuK/wNzpPDOGYrcMfSNwYmgoxHAV2/3WfAGB7jQasYsHoHc0VcXJxlPKDhPVGsJtOaL63ne4MHQ8a4lj12qbTY9QncIfqx4sjH8W48yzrye7Bl5RPvwxQ0DYQmPGpugBsxhqd4ECtgsWNYL4pJYcWKFZbxgAXWlmoVtfB8tfnnz/MmD0aM4X89d+xOW6F4BFcncGdxC4Xekf8MhM8hD1tJjEHaGJaxJZh+OH6I3ga4AWN4jAe5gqY09PgoYvPmzZbxgDf8dpLQPSlwMU7M4MGIMfq05T6b74jg+gVetH34seOfP51D4pbFMaRLYjSr/za0guuZ0tUAN2AMj/GAnxVDmcuLH8vgMzlgETXLeIAx8pXMLUwXyyt6lI75Ag9GjHGvexRXEDeJH+JuzRp9u3j78Nzocb9Ihpgjgd/MePGBaeX/ePpIx7HROEcOv0a6O65njfo/rmdKVwPcgDE8ygNmqk7DBLgjSgaQSsd0c8t4UDK1WDrlA/d8G4bIHTt2bLcerOZBtzEa0kNHiUdwaVG3ZoXdPvDnoD1DA+6jBb7odVOa30SPP/TTxY/RfuIrD7584vOQ3RD6rY7cMCaOUTjujlnRA2L0NsD1GsNbPEyZMuVlRM7dEM0tKRMgQjMxREVFmc4DJg+O0mpmMsTHH3+8Z9CgQZJ6sIoHvcbwu5YRNkcscjsfcwi7NXPU7fQ/DeENEcFFdvq9C3oHm6aH00tQBNp/CHji2eE/D8/ZOvTv1zNH3urICWXSGMnacxxYt2ggLR6mqwGu0xhe5yEkJCR8y5YtfyeDSBmBP56ZmckImK9kOg/4sck5ao1Bhvjoo494Q6jSg9k86DbG9czQTxzRXDx6d+SMYpcPj2j73xWDNkOsr3E1xCgSPUC/jkSj1NS1SgNywhXF6RilkUGGPBNy/4ScrUO2XTkyvLU9ZwQMIIHsp1nWlie34xqaTKj5Z8n0GsMsHoYNGzYBBtmGdx5aeQOIbdEzxNAAN50HiP0TMoacedGd25aSkmJID2bxoNcY/m1ZI/Pco7gjcl8+/HTbX1cO+gQCpXWcxgH03jU9KlHDmLpTlV4g4td1oink/8ZdG7x/Y+Cqq0dCWtqzh7NuZGGfw5mvhhbhXJoaorkBrtMYlvCwfv36VTBIC5lADHiDz3QecB95YqYg85Ih0I3scT14kwe9xrjnRvaITtfoXb0nuGbDkoEfQpg0DZxGoml1Dmo/8IbgawccUvXHG4TMRP+D/lfwvvWDUy+mBze0Z4YwIa4cCm5FOk0N0dwA12kMS3nAi0mpeLZvQLSmBmw3Dhw4YDoPMEanaw321Vdf1WCmq9f14A0edBmjYldQYDseXRwYzqr3PFWTkvAQDSzxNcRQF0Mo1RBKLuENQu0QMgjVPsEfv/3ogvpvgsrbM4NhEAd+PfQ+WiaGXljSNAKuxxi+wsPixYsXfP311+VCcwQFBZnGwxdffBEorLnIEPHx8abrwZM86DGG3+WDw2Lp8aVsZ9DR95MeThGpIfrhGInYqCFcDUMGoVrHqQb58zuPzG/Y++Tp9owg9tHihxdwxqHvVz0CrsMYPsfDkiVL5mMJztNHjx5liNSm8ZCenh5LxtixY8fRxMREy/XgCR50GaPhm6ETV89/hFbiCOUeXYQ1BAlS6yOTUo0hZhAyHX0XmZDmSAUlTO43JXXeg7Q6Bj1yaZoaoscYvspDdHT0lLlz55rGA2qricnJyT6nByM86DIG95hCjWJaB5Z6j2iZGm/UEEqG4WsQ+m66B3qEonvqD2h6m0+PMe7y0FU8VAb02Nqr9KDHGEQGvQxEZFBUFna5KgnZW+m8QcgM1JNFW03vZegwxl0eekqz1+nh/wHpt113GQ6n7AAAAABJRU5ErkJggg==); + background-position: left center; + background-repeat: no-repeat; + width: 24px; + height: 20px; + display: inline-block; + background-size: cover; +} + +.galleryImage { + width: 120px; + display: inline-block; + margin: 5px; +} + +.halfStarRating { + background-position: center center; +} + +.emptyStarRating { + background-position: right center; +} + +@media all and (min-width: 650px) { + .itemImageBlock { + display: inline-block; + } + + .itemDetailImage, .itemImageBlock { + max-width: 220px; + } + + .itemDetailBlock { + padding-top: 0; + display: inline-block; + width: 45%; + padding-left: 20px; + max-width: 800px; + } + + .galleryImage { + width: 150px; + } +} + +@media all and (min-width: 750px) { + + .itemDetailImage, .itemImageBlock { + max-width: 300px; + } + + .itemDetailBlock { + padding-left: 30px; + } +} + + +@media all and (min-width: 1200px) { + + .itemDetailImage, .itemImageBlock { + max-width: 400px; + } + + .itemDetailBlock { + width: 55%; + } + + .galleryImage { + width: 200px; + } +} + +/* Now playing bar */ +#nowPlayingBar { + padding: 10px 20px 8px; + border-top: 1px solid #5490CC; +} + +.mediaButton { + margin: 0 20px 0 0; + display: inline-block; +} + +#mediaElement { + margin-right: 20px; + display: inline-block; + position: relative; +} + +.mediaButton img { + height: 28px; +} + +.itemVideo { + position: absolute; + z-index: 99998; + height: auto; + width: 180px; + bottom: -5px; +} + +@media all and (min-width: 650px) { + + .itemVideo { + width: 270px; + } +} diff --git a/MediaBrowser.WebDashboard/Html/dashboard.html b/MediaBrowser.WebDashboard/Html/dashboard.html new file mode 100644 index 0000000000..805c9c45e8 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/dashboard.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html> +<head> + <title>Dashboard</title> +</head> +<body> + <div id="dashboardPage" data-role="page" class="page type-interior"> + + <div data-role="content"> + <div class="content-primary"> + <div class="readOnlyContent"> + <div data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em;"> + <h3>Server Information</h3> + <div> + <p> + Version <span id="appVersionNumber"></span> + </p> + <p id="pUpToDate" style="display: none;"> + <img src="css/images/checkMarkGreen.png" style="height: 20px; margin-right: 3px; position: relative; top: 4px;" /> + Media Browser Server is up to date + </p> + <div id="pUpdateNow" style="display: none;"> + <p><strong>A new version of Media Browser Server is available!</strong></p> + <p id="newVersionNumber"></p> + <button id="btnUpdateApplication" type="button" data-icon="download" data-theme="b" onclick="DashboardPage.updateApplication();">Update Now</button> + </div> + </div> + </div> + + <div data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em; display: none;" id="collapsiblePluginUpdates"> + <h3>Plugin Information</h3> + <div id="pPluginUpdates"></div> + </div> + + <div data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em;"> + <h3>Active Connections</h3> + <div id="divConnections"> + </div> + </div> + + <div data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em;"> + <h3>Running Tasks</h3> + <div id="divRunningTasks"> + </div> + <p><a href="scheduledTasks.html">Manage Scheduled Tasks</a></p> + </div> + </div> + </div> + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/editUser.html b/MediaBrowser.WebDashboard/Html/editUser.html new file mode 100644 index 0000000000..85ae14132e --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/editUser.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html> +<head> + <title></title> +</head> +<body> + <div id="editUserPage" data-role="page" class="page type-interior userProfilesConfigurationPage"> + + <div data-role="content"> + <div class="content-primary"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" id="userProfileNavigation" style="display: none;" data-mini="true"> + <a href="#" data-role="button" class="ui-btn-active">Profile</a> + <a href="#" data-role="button" onclick="Dashboard.navigate('userImage.html', true);">Image</a> + <a href="#" data-role="button" onclick="Dashboard.navigate('updatePassword.html', true);">Password</a> + <a href="#" data-role="button" onclick="Dashboard.navigate('library.html', true);">Media Library</a> + </div> + <form id="editUserProfileForm"> + <ul data-role="listview" class="ulForm"> + <li id="fldUserName"> + <label for="txtUserName">Name: </label> + <input id="txtUserName" name="txtUserName" required="required" type="text" /> + </li> + <li id="fldMaxParentalRating" style="display: none;"> + <label for="selectMaxParentalRating">Max parental rating:</label> + <select name="selectMaxParentalRating" id="selectMaxParentalRating"></select> + </li> + <li id="fldIsAdmin" style="display: none;"> + <input type="checkbox" id="chkIsAdmin" name="chkIsAdmin" /> + <label for="chkIsAdmin">Allow this user to manage the server</label> + </li> + </ul> + <h2>Video Playback Settings</h2> + <ul data-role="listview" class="ulForm"> + <li> + <label for="selectAudioLanguage">Audio language preference: </label> + <select name="selectAudioLanguage" id="selectAudioLanguage"></select> + </li> + <li> + <label for="selectSubtitleLanguage">Subtitle language preference: </label> + <select name="selectSubtitleLanguage" id="selectSubtitleLanguage"></select> + </li> + <li> + <input type="checkbox" id="chkForcedSubtitlesOnly" name="chkForcedSubtitlesOnly" /> + <label for="chkForcedSubtitlesOnly">Display only forced subtitles</label> + </li> + <li> + <button type="submit" data-theme="b" data-icon="ok"> + Save + </button> + <button type="button" onclick="history.back();" data-icon="delete"> + Cancel + </button> + </li> + </ul> + </form> + </div> + </div> + <script type="text/javascript"> + $('#editUserProfileForm').on('submit', EditUserPage.onSubmit); + </script> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/favicon.ico b/MediaBrowser.WebDashboard/Html/favicon.ico Binary files differnew file mode 100644 index 0000000000..1541dabdc4 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/favicon.ico diff --git a/MediaBrowser.WebDashboard/Html/index.html b/MediaBrowser.WebDashboard/Html/index.html new file mode 100644 index 0000000000..960f49533a --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/index.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> + <title>Media Browser</title> +</head> +<body> + <div id="indexPage" data-role="page" class="page type-home libraryPage" data-theme="a"> + <div data-role="content"> + <h1>What's New <a href="#" class="imageLink"> + <img src="css/images/rightArrow.png" /></a></h1> + + <div id="divWhatsNew"></div> + + <div id="divResumable" style="display: none;"> + <h1>Resume <a href="#" class="imageLink"> + <img src="css/images/rightArrow.png" /></a></h1> + + <div id="divResumableItems"></div> + </div> + + <h1>My Library <a href="#" class="imageLink"> + <img src="css/images/rightArrow.png" /></a></h1> + + <div id="divMyLibrary"></div> + + <h1>Collections <a href="#" class="imageLink"> + <img src="css/images/rightArrow.png" /></a></h1> + + <div id="divCollections"></div> + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/itemDetails.html b/MediaBrowser.WebDashboard/Html/itemDetails.html new file mode 100644 index 0000000000..6dac0a486e --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/itemDetails.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<html> +<head> + <title></title> +</head> +<body> + <div id="itemDetailPage" data-role="page" class="page libraryPage" data-theme="a"> + <div data-role="content" style="padding-top: 0;"> + + <h1 id="itemName" style="padding-left: 10px; margin: 0;"></h1> + + <div style="padding: 10px;"> + <div class="itemImageBlock"> + <div id="itemMedia" style="position: relative;"> + <div id="itemImage"></div> + <div id="playButtonShadow" style="display: none; height: 48px; position: absolute; bottom: 0; left: 0; right: 0; background: black; opacity: .75;"> + </div> + <button id="btnPlay" type="button" class="imageButton" style="display: none; position: absolute; bottom: 5px; left: 10px;" data-role="none" title="Play" onclick="ItemDetailPage.play();"> + <img src="css/images/media/playCircle.png" style="height: 28px;" /> + </button> + </div> + </div> + + <div class="itemDetailBlock"> + + <p id="itemTagline" style="font-style: italic;"></p> + <p id="itemOverview"></p> + <p id="itemCommunityRating"></p> + <p id="itemMiscInfo" style="color: #ddd; font-size: 14px;"></p> + + <p id="itemGenres"> + </p> + + <p id="itemStudios"> + </p> + </div> + </div> + + <div data-role="collapsible" data-content-theme="a" id="mediaInfoCollapsible"> + <h3>Media Info</h3> + <div id="mediaInfoContent"></div> + </div> + <div data-role="collapsible" data-content-theme="a" id="scenesCollapsible"> + <h3>Scenes</h3> + <div id="scenesContent"></div> + </div> + <div data-role="collapsible" data-content-theme="a"> + <h3>Special Features</h3> + <p>I'm the collapsible content. By default I'm closed, but you can click the header to open me.</p> + </div> + <div data-role="collapsible" data-content-theme="a"> + <h3>Trailers</h3> + <p>I'm the collapsible content. By default I'm closed, but you can click the header to open me.</p> + </div> + <div data-role="collapsible" data-content-theme="a"> + <h3>Cast & Crew</h3> + <p>I'm the collapsible content. By default I'm closed, but you can click the header to open me.</p> + </div> + <div data-role="collapsible" data-content-theme="a"> + <h3>Gallery</h3> + <div id="galleryContent"></div> + </div> + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/library.html b/MediaBrowser.WebDashboard/Html/library.html new file mode 100644 index 0000000000..9ba35b03ac --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/library.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html> +<head> + <title> </title> +</head> +<body> + <div id="mediaLibraryPage" data-role="page" class="page type-interior mediaLibraryPage"> + + <div data-role="content"> + <div class="content-primary"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" id="userProfileNavigation" style="display: none;" data-mini="true"> + <a href="#" data-role="button" onclick="Dashboard.navigate('editUser.html', true);">Profile</a> + <a href="#" data-role="button" onclick="Dashboard.navigate('userImage.html', true);">Image</a> + <a href="#" data-role="button" onclick="Dashboard.navigate('updatePassword.html', true);">Password</a> + <a href="#" data-role="button" class="ui-btn-active">Media Library</a> + </div> + <div class="readOnlyContent"> + <p id="fldUseDefaultLibrary" style="display: none;"> + <input type="checkbox" id="chkUseDefaultLibrary" name="chkUseDefaultLibrary" onchange="MediaLibraryPage.setUseDefaultMediaLibrary(this.checked);" /> + <label for="chkUseDefaultLibrary">Use default media library</label> + </p> + <div id="divMediaLibrary"> + <p>Below are your media collections. Expand a collection to add or remove media locations assigned to it.</p> + <p> + <button type="button" data-icon="plus" onclick="MediaLibraryPage.addVirtualFolder();">Add media collection</button> + </p> + <div id="divVirtualFolders"></div> + </div> + </div> + </div> + </div> + <div data-role="popup" id="popupEnterText" class="ui-corner-all popup"> + + <div class="ui-corner-top ui-bar-a" style="text-align: center; padding: 0 20px;"> + <h3>Rename</h3> + </div> + + <div data-role="content" class="ui-corner-bottom ui-content"> + <form id="textEntryForm"> + <label for="txtValue">New name:</label> + <input type="text" name="txtValue" id="txtValue" required="required" /> + + <p> + <button type="submit" data-theme="b" data-icon="ok"> + Ok + </button> + <button type="button" data-icon="delete" onclick="$(this).parents('.popup').popup('close');"> + Cancel + </button> + </p> + </form> + </div> + + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/log.html b/MediaBrowser.WebDashboard/Html/log.html new file mode 100644 index 0000000000..db76240ffa --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/log.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> +<head> + <title>Log File</title> +</head> +<body> + <div id="logPage" data-role="page" class="page type-interior"> + + <div data-role="content"> + <div class="content-primary"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> + <a href="support.html" data-role="button">General</a> + <a href="log.html" data-role="button" class="ui-btn-active">View Log</a> + <a href="supporter.html" data-role="button">Become a Supporter</a> + <a href="supporterKey.html" data-role="button">Supporter Key</a> + </div> + <p> + <label for="chkAutoScroll">Auto-scroll</label> + <input type="checkbox" id="chkAutoScroll" onchange="LogPage.updateAutoScroll(this.checked);" name="chkAutoScroll" data-inline="true" /> + </p> + <textarea id="logContents" class="pre" style="overflow-y:hidden;"></textarea> + <p> + <label for="chkAutoScrollBottom">Auto-scroll</label> + <input type="checkbox" id="chkAutoScrollBottom" name="chkAutoScrollBottom" onchange="LogPage.updateAutoScroll(this.checked);" data-inline="true" /> + </p> + </div> + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/login.html b/MediaBrowser.WebDashboard/Html/login.html new file mode 100644 index 0000000000..4cb73c06ef --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/login.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html> +<head> + <title>Sign In</title> +</head> +<body> + <div id="loginPage" data-role="page" class="page standalonePage"> + + <div data-role="content"> + <div id="divUsers" style="margin: 50px 20px 20px; text-align: center;"></div> + </div> + + <div data-role="popup" id="popupLogin" class="ui-corner-all popup"> + <form id="loginForm"> + <div class="ui-corner-top ui-bar-a" style="text-align: center;"> + <h3>Please sign in</h3> + </div> + <div data-role="content" class="ui-corner-bottom ui-content"> + <label for="pw" class="ui-hidden-accessible">Password:</label> + <input type="password" name="pw" id="pw" value="" placeholder="password" /> + + <p> + <button type="submit" data-theme="b" data-icon="ok"> + Sign in + </button> + <button type="button" data-icon="delete" onclick="$(this).parents('.popup').popup('close');"> + Cancel + </button> + </p> + </div> + </form> + </div> + + <script type="text/javascript"> + $('#loginForm').on('submit', LoginPage.onSubmit); + </script> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/metadata.html b/MediaBrowser.WebDashboard/Html/metadata.html new file mode 100644 index 0000000000..4618dd4bd8 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/metadata.html @@ -0,0 +1,59 @@ +<!DOCTYPE html> +<html> +<head> + <title>Metadata</title> +</head> +<body> + <div id="metadataConfigurationPage" data-role="page" class="page type-interior"> + + <div data-role="content"> + + <div class="content-primary"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> + <a href="metadata.html" data-role="button" class="ui-btn-active">Basics</a> + <a href="metadataImages.html" data-role="button">Images</a> + <a href="advancedMetadata.html" data-role="button">Advanced</a> + </div> + + <form id="metadataConfigurationForm"> + <ul data-role="listview" class="ulForm"> + <li> + <input type="checkbox" id="chkEnableInternetProviders" name="chkEnableInternetProviders" /> + <label for="chkEnableInternetProviders">Download metadata from the internet </label> + </li> + <li> + <input type="checkbox" id="chkSaveLocal" name="chkSaveLocal" /> + <label for="chkSaveLocal">Save metadata within media folders </label> + </li> + <li> + <label for="txtRefreshDays">Metadata refresh period (days): </label> + <input type="number" id="txtRefreshDays" name="txtRefreshDays" pattern="[0-9]*" required="required" min="1" /> + </li> + <li> + <label for="selectLanguage">Preferred language: </label> + <select name="selectLanguage" id="selectLanguage"></select> + </li> + <li> + <label for="selectCountry">Country: </label> + <select name="selectCountry" id="selectCountry"></select> + </li> + <li> + <button type="submit" data-theme="b"> + Save + </button> + <button type="button" onclick="Dashboard.navigate('dashboard.html');"> + Cancel + </button> + </li> + </ul> + </form> + </div> + + </div> + + <script type="text/javascript"> + $('#metadataConfigurationForm').on('submit', MetadataConfigurationPage.onSubmit); + </script> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/metadataImages.html b/MediaBrowser.WebDashboard/Html/metadataImages.html new file mode 100644 index 0000000000..5c9e7e02d2 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/metadataImages.html @@ -0,0 +1,120 @@ +<!DOCTYPE html> +<html> +<head> + <title>Metadata</title> +</head> +<body> + <div id="metadataImagesConfigurationPage" data-role="page" class="page type-interior"> + + <div data-role="content"> + + <div class="content-primary"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> + <a href="metadata.html" data-role="button">Basics</a> + <a href="metadataImages.html" data-role="button" class="ui-btn-active">Images</a> + <a href="advancedMetadata.html" data-role="button">Advanced</a> + </div> + + <form id="metadataImagesConfigurationForm"> + <ul data-role="listview" class="ulForm"> + <li> + <input type="checkbox" id="chkRefreshItemImages" name="chkRefreshItemImages" /> + <label for="chkRefreshItemImages">Refresh existing images </label> + <div class="fieldDescription"> + When enabled, images will be refreshed periodically + </div> + </li> + <li> + <label for="txtNumbackdrops">Max number of backdrops per item: </label> + <input type="number" id="txtNumbackdrops" name="txtNumbackdrops" pattern="[0-9]*" required="required" min="1" /> + </li> + <li> + <label>Enable additional image downloading:</label> + <div data-role="controlgroup"> + + <input type="checkbox" data-mini="true" id="chkDownloadMovieArt" name="chkDownloadMovieArt" /> + <label for="chkDownloadMovieArt">Movie Art</label> + + <input type="checkbox" data-mini="true" id="chkDownloadMovieBanner" name="chkDownloadMovieBanner" /> + <label for="chkDownloadMovieBanner">Movie Banner</label> + + <input type="checkbox" data-mini="true" id="chkDownloadMovieDisc" name="chkDownloadMovieDisc" /> + <label for="chkDownloadMovieDisc">Movie Disc</label> + + <input type="checkbox" data-mini="true" id="chkDownloadMovieLogo" name="chkDownloadMovieLogo" /> + <label for="chkDownloadMovieLogo">Movie Logo</label> + + <input type="checkbox" data-mini="true" id="chkDownloadMovieThumb" name="chkDownloadMovieThumb" /> + <label for="chkDownloadMovieThumb">Movie Thumb</label> + + <input type="checkbox" data-mini="true" id="chKDownloadTVArt" name="chKDownloadTVArt" /> + <label for="chKDownloadTVArt">TV Series Art</label> + + <input type="checkbox" data-mini="true" id="chkDownloadTVBanner" name="chkDownloadTVBanner" /> + <label for="chkDownloadTVBanner">TV Series Banner</label> + + <input type="checkbox" data-mini="true" id="chkDownloadTVLogo" name="chkDownloadTVLogo" /> + <label for="chkDownloadTVLogo">TV Series Logo</label> + + <input type="checkbox" data-mini="true" id="chkDownloadTVThumb" name="chkDownloadTVThumb" /> + <label for="chkDownloadTVThumb">TV Series Thumb</label> + + <input type="checkbox" data-mini="true" id="chkDownloadSeasonBackdrops" name="chkDownloadSeasonBackdrops" /> + <label for="chkDownloadSeasonBackdrops">TV Season Backdrops</label> + + <input type="checkbox" data-mini="true" id="chkDownloadSeasonBanner" name="chkDownloadSeasonBanner" /> + <label for="chkDownloadSeasonBanner">TV Season Banner</label> + + <input type="checkbox" data-mini="true" id="chkDownloadSeasonThumb" name="chkDownloadSeasonThumb" /> + <label for="chkDownloadSeasonThumb">TV Season Thumb</label> + </div> + </li> + <li> + <label for="selectTmdbPosterDownloadSize">Tmdb poster download size: </label> + <select id="selectTmdbPosterDownloadSize" name="selectTmdbPosterDownloadSize"> + <option value="original">original</option> + <option value="w92">w92</option> + <option value="w154">w154</option> + <option value="w185">w185</option> + <option value="w342">w342</option> + <option value="w500">w500</option> + </select> + </li> + <li> + <label for="selectTmdbBackdropDownloadSize">Tmdb backdrop download size: </label> + <select id="selectTmdbBackdropDownloadSize" name="selectTmdbBackdropDownloadSize"> + <option value="original">original</option> + <option value="w380">w380</option> + <option value="w780">w780</option> + <option value="w1280">w1280</option> + </select> + </li> + <li> + <label for="selectTmdbPersonImageDownloadSize">Tmdb person image download size: </label> + <select id="selectTmdbPersonImageDownloadSize" name="selectTmdbPersonImageDownloadSize"> + <option value="original">original</option> + <option value="w45">w45</option> + <option value="w185">w185</option> + <option value="h632">h632</option> + </select> + </li> + <li> + <button type="submit" data-theme="b"> + Save + </button> + <button type="button" onclick="Dashboard.navigate('dashboard.html');"> + Cancel + </button> + </li> + </ul> + </form> + </div> + + </div> + + <script type="text/javascript"> + $('#metadataImagesConfigurationForm').on('submit', MetadataImagesPage.onSubmit); + </script> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/pluginCatalog.html b/MediaBrowser.WebDashboard/Html/pluginCatalog.html new file mode 100644 index 0000000000..1b5ad74286 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/pluginCatalog.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> + <title>Plugins</title> +</head> +<body> + <div id="pluginCatalogPage" data-role="page" class="page type-interior pluginConfigurationPage"> + + <div data-role="content"> + <div class="content-primary"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> + <a href="plugins.html" data-role="button">Installed Plugins</a> + <a href="pluginCatalog.html" data-role="button" class="ui-btn-active">Plugin Catalog</a> + <a href="pluginUpdates.html" data-role="button">Automatic Updates</a> + </div> + + <div id="pluginTiles"></div> + </div> + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/pluginUpdates.html b/MediaBrowser.WebDashboard/Html/pluginUpdates.html new file mode 100644 index 0000000000..ed5ba54b11 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/pluginUpdates.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html> +<head> + <title>Plugins</title> +</head> +<body> + <div id="pluginUpdatesPage" data-role="page" class="page type-interior pluginConfigurationPage"> + + <div data-role="content"> + <div class="content-primary"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> + <a href="plugins.html" data-role="button">Installed Plugins</a> + <a href="pluginCatalog.html" data-role="button">Plugin Catalog</a> + <a href="pluginUpdates.html" data-role="button" class="ui-btn-active">Automatic Updates</a> + </div> + + <form id="pluginUpdatesForm"> + + <table id="tblPluginUpdates"> + <thead> + <tr> + <th></th> + <th>Automatic updates</th> + <th>Update level</th> + </tr> + </thead> + <tbody id="tbodyPluginUpdates"></tbody> + </table> + </form> + </div> + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/plugins.html b/MediaBrowser.WebDashboard/Html/plugins.html new file mode 100644 index 0000000000..ee74ae3756 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/plugins.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> +<head> + <title>Plugins</title> +</head> +<body> + <div id="pluginsPage" data-role="page" class="page type-interior pluginConfigurationPage"> + + <div data-role="content"> + <div class="content-primary"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> + <a href="plugins.html" data-role="button" class="ui-btn-active">Installed Plugins</a> + <a href="pluginCatalog.html" data-role="button">Plugin Catalog</a> + <a href="pluginUpdates.html" data-role="button">Automatic Updates</a> + </div> + + <div class="readOnlyContent"> + <ul id="ulInstalledPlugins" data-role="listview" data-inset="true" data-auto-enhanced="false" data-split-icon="minus"></ul> + </div> + </div> + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/scheduledTask.html b/MediaBrowser.WebDashboard/Html/scheduledTask.html new file mode 100644 index 0000000000..fbfe3cc715 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scheduledTask.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<html> +<head> + <title></title> +</head> +<body> + <div id="scheduledTaskPage" data-role="page" class="page type-interior"> + <div data-role="content"> + <div class="content-primary"> + <div class="readOnlyContent"> + <p id="pTaskDescription"></p> + <p> + <button type="button" data-icon="plus" onclick="ScheduledTaskPage.showAddTriggerPopup();"> + Add Task Trigger + </button> + </p> + <ul id="ulTaskTriggers" data-role="listview" data-inset="true" data-auto-enhanced="false" data-split-icon="minus"></ul> + </div> + </div> + </div> + <div data-role="popup" id="popupAddTrigger" class="ui-corner-all popup" style="min-width: 300px;"> + <form id="addTriggerForm"> + <div class="ui-corner-top ui-bar-a" style="text-align: center; padding: 0 20px;"> + <h3>Add Task Trigger</h3> + </div> + <div data-role="content" class="ui-corner-bottom ui-content"> + + <ul data-role="listview" class="ulForm"> + <li> + <label for="selectTriggerType">Trigger Type:</label> + <select id="selectTriggerType" name="selectTriggerType" onchange="ScheduledTaskPage.refreshTriggerFields(this.value);"> + <option value="DailyTrigger">Daily</option> + <option value="WeeklyTrigger">Weekly</option> + <option value="IntervalTrigger">On an interval</option> + <option value="StartupTrigger">On application startup</option> + <option value="SystemEventTrigger">After a system event</option> + </select> + </li> + <li id="fldDayOfWeek"> + <label for="selectDayOfWeek">Day:</label> + <select id="selectDayOfWeek" name="selectDayOfWeek"> + <option value="Sunday">Sunday</option> + <option value="Monday">Monday</option> + <option value="Tuesday">Tuesday</option> + <option value="Wednesday">Wednesday</option> + <option value="Thursday">Thursday</option> + <option value="Friday">Friday</option> + <option value="Saturday">Saturday</option> + </select> + </li> + <li id="fldTimeOfDay"> + <label for="txtTimeOfDay">Time:</label> + <input type="time" id="txtTimeOfDay" name="txtTimeOfDay" required="required" /> + </li> + <li id="fldSelectSystemEvent"> + <label for="selectSystemEvent">Event:</label> + <select id="selectSystemEvent" name="selectSystemEvent"> + <option value="WakeFromSleep">Wake from sleep</option> + </select> + </li> + <li id="fldSelectInterval"> + <label for="selectInterval">Every:</label> + <select id="selectInterval" name="selectInterval"> + <option value="9000000000">15 minutes</option> + <option value="18000000000">30 minutes</option> + <option value="27000000000">45 minutes</option> + <option value="36000000000">1 hour</option> + <option value="72000000000">2 hours</option> + <option value="108000000000">3 hours</option> + <option value="144000000000">4 hours</option> + <option value="216000000000">6 hours</option> + <option value="288000000000">8 hours</option> + <option value="432000000000">12 hours</option> + </select> + </li> + <li> + <button type="submit" data-theme="b" data-icon="ok"> + Add + </button> + <button type="button" data-icon="delete" onclick="$(this).parents('.popup').popup('close');"> + Cancel + </button> + </li> + </ul> + </div> + </form> + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/scheduledTasks.html b/MediaBrowser.WebDashboard/Html/scheduledTasks.html new file mode 100644 index 0000000000..dfbac291b5 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scheduledTasks.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> + <title>Scheduled Tasks</title> +</head> +<body> + <div id="scheduledTasksPage" data-role="page" class="page type-interior"> + <div data-role="content"> + <div class="content-primary"> + <div class="readOnlyContent"> + <p>Below are Media Browser's scheduled tasks. Click into a task to adjust it's schedule.</p> + <ul id="ulScheduledTasks" data-role="listview" data-inset="true" data-auto-enhanced="false" data-split-icon="Play"></ul> + </div> + </div> + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/scripts/AddPluginPage.js b/MediaBrowser.WebDashboard/Html/scripts/AddPluginPage.js new file mode 100644 index 0000000000..e8cf82e869 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/AddPluginPage.js @@ -0,0 +1,243 @@ +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 += "You have never installed this feature"; + } else { + if (pkg.expDate <= new Date().getTime()) { + regStatus += "The trial period for this feature has expired on this machine"; + } 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 || ""); + // Fill in PayPal info + $('#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 { + $('#regInfo', page).html("<h3>You must be a <a href='supporter.html'>Media Browser Supporter</a> in order to register 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);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/AdvancedConfigurationPage.js b/MediaBrowser.WebDashboard/Html/scripts/AdvancedConfigurationPage.js new file mode 100644 index 0000000000..5c6f282fb0 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/AdvancedConfigurationPage.js @@ -0,0 +1,63 @@ +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(); + } + + $('#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(); + + ApiClient.updateServerConfiguration(config).done(Dashboard.processServerConfigurationUpdateResult); + }); + + // Disable default form submission + return false; + } +}; + +$(document).on('pageshow', "#advancedConfigurationPage", AdvancedConfigurationPage.onPageShow); diff --git a/MediaBrowser.WebDashboard/Html/scripts/AdvancedMetadataConfigurationPage.js b/MediaBrowser.WebDashboard/Html/scripts/AdvancedMetadataConfigurationPage.js new file mode 100644 index 0000000000..73ed3f4311 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/AdvancedMetadataConfigurationPage.js @@ -0,0 +1,65 @@ +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 + '" />'; + html += '<label for="' + id + '">' + type + '</label>'; + } + + html += "</div>"; + + $('#divItemTypes', page).html(html).trigger("create"); + }, + + onSubmit: function () { + Dashboard.showLoadingMsg(); + + var form = this; + + ApiClient.getServerConfiguration().done(function (config) { + + config.InternetProviderExcludeTypes = $.map($('.chkItemType:checked', form), function (currentCheckbox) { + + return currentCheckbox.getAttribute('data-itemtype'); + }); + + ApiClient.updateServerConfiguration(config).done(Dashboard.processServerConfigurationUpdateResult); + }); + + // Disable default form submission + return false; + } +}; + +$(document).on('pageshow', "#advancedMetadataConfigurationPage", AdvancedMetadataConfigurationPage.onPageShow);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/DashboardPage.js b/MediaBrowser.WebDashboard/Html/scripts/DashboardPage.js new file mode 100644 index 0000000000..93163de79d --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/DashboardPage.js @@ -0,0 +1,423 @@ +var DashboardPage = { + + onPageShow: function () { + + Dashboard.showLoadingMsg(); + DashboardPage.pollForInfo(); + DashboardPage.startInterval(); + $(document).on("websocketmessage", DashboardPage.onWebSocketMessage).on("websocketopen", DashboardPage.onWebSocketConnectionChange).on("websocketerror", DashboardPage.onWebSocketConnectionChange).on("websocketclose", DashboardPage.onWebSocketConnectionChange); + + DashboardPage.lastAppUpdateCheck = null; + DashboardPage.lastPluginUpdateCheck = null; + }, + + onPageHide: function () { + + $(document).off("websocketmessage", DashboardPage.onWebSocketMessage).off("websocketopen", DashboardPage.onWebSocketConnectionChange).off("websocketerror", DashboardPage.onWebSocketConnectionChange).off("websocketclose", DashboardPage.onWebSocketConnectionChange); + DashboardPage.stopInterval(); + }, + + startInterval: function () { + + if (Dashboard.isWebSocketOpen()) { + Dashboard.sendWebSocketMessage("DashboardInfoStart", "0,1500"); + } + }, + + stopInterval: function () { + + if (Dashboard.isWebSocketOpen()) { + Dashboard.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) { + + if (connection.ClientType == "Dashboard") { + + return "<img src='css/images/clients/html5.png' alt='Dashboard' title='Dashboard' />"; + } + if (connection.ClientType == "Pc") { + + return "<img src='css/images/clients/mb.png' alt='Media Browser' title='Media Browser' />"; + } + if (connection.ClientType == "Android") { + + return "<img src='css/images/clients/android.png' alt='Android' title='Android' />"; + } + if (connection.ClientType == "Ios") { + + return "<img src='css/images/clients/ios.png' alt='iOS' title='iOS' />"; + } + if (connection.ClientType == "WindowsRT") { + + return "<img src='css/images/clients/windowsrt.png' alt='Windows RT' title='Windows RT' />"; + } + if (connection.ClientType == "WindowsPhone") { + + return "<img src='css/images/clients/windowsphone.png' alt='Windows Phone' title='Windows Phone' />"; + } + + return connection.ClientType; + }, + + getNowPlayingImage: function (item) { + + if (item) { + + if (item.BackdropImageTag) { + var url = ApiClient.getImageUrl(item.Id, { + type: "Backdrop", + height: 100, + tag: item.BackdropImageTag + }); + + return "<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 = task.CurrentProgress || { PercentComplete: 0 }; + html += '<span style="color:#267F00;margin-right:5px;font-weight:bold;"> - ' + Math.round(progress.PercentComplete) + '%</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); + }, + + renderApplicationUpdateInfo: function (dashboardInfo) { + + var page = $.mobile.activePage; + + if (dashboardInfo.SystemInfo.IsNetworkDeployed && !dashboardInfo.SystemInfo.HasPendingRestart) { + + // Only check once every 10 mins + if (DashboardPage.lastAppUpdateCheck && (new Date().getTime() - DashboardPage.lastAppUpdateCheck) < 600000) { + return; + } + + DashboardPage.lastAppUpdateCheck = new Date().getTime(); + + ApiClient.getAvailableApplicationUpdate().done(function (packageInfo) { + + var version = packageInfo.versions[0]; + + if (!version) { + $('#pUpToDate', page).show(); + $('#pUpdateNow', page).hide(); + } else { + $('#pUpToDate', page).hide(); + + $('#pUpdateNow', page).show(); + + $('#newVersionNumber', page).html("Version " + version.versionStr + " is now available for download."); + } + + }).fail(function () { + + Dashboard.showFooterNotification({ html: '<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(); + } + }, + + renderPluginUpdateInfo: function (dashboardInfo) { + + // Only check once every 10 mins + if (DashboardPage.lastPluginUpdateCheck && (new Date().getTime() - DashboardPage.lastPluginUpdateCheck) < 600000) { + return; + } + + DashboardPage.lastPluginUpdateCheck = new Date().getTime(); + + var page = $.mobile.activePage; + + ApiClient.getAvailablePluginUpdates().done(function (updates) { + + if (updates.length) { + + $('#collapsiblePluginUpdates', page).show(); + + } else { + $('#collapsiblePluginUpdates', page).hide(); + + return; + } + var html = ''; + + for (var i = 0, length = updates.length; i < length; i++) { + + var update = updates[i]; + + html += '<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>'; + } + + $('#pPluginUpdates', page).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);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/DisplaySettingsPage.js b/MediaBrowser.WebDashboard/Html/scripts/DisplaySettingsPage.js new file mode 100644 index 0000000000..da87a106f7 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/DisplaySettingsPage.js @@ -0,0 +1,46 @@ +var DisplaySettingsPage = { + + onPageShow: function () { + Dashboard.showLoadingMsg(); + + var page = this; + + ApiClient.getServerConfiguration().done(function (config) { + + $('#txtWeatherLocation', page).val(config.WeatherLocation); + $('#txtMinResumePct', page).val(config.MinResumePct); + $('#txtMaxResumePct', page).val(config.MaxResumePct); + $('#txtMinResumeDuration', page).val(config.MinResumeDurationSeconds); + $('#selectWeatherUnit', page).val(config.WeatherUnit).selectmenu("refresh"); + + Dashboard.hideLoadingMsg(); + }); + + }, + + submit: function() { + + $('.btnSubmit', $.mobile.activePage)[0].click(); + + }, + + onSubmit: function () { + var form = this; + + ApiClient.getServerConfiguration().done(function (config) { + + config.WeatherLocation = $('#txtWeatherLocation', form).val(); + config.WeatherUnit = $('#selectWeatherUnit', form).val(); + config.MinResumePct = $('#txtMinResumePct', form).val(); + config.MaxResumePct = $('#txtMaxResumePct', form).val(); + config.MinResumeDurationSeconds = $('#txtMinResumeDuration', form).val(); + + ApiClient.updateServerConfiguration(config); + }); + + // Disable default form submission + return false; + } +}; + +$(document).on('pageshow', "#displaySettingsPage", DisplaySettingsPage.onPageShow); diff --git a/MediaBrowser.WebDashboard/Html/scripts/EditUserPage.js b/MediaBrowser.WebDashboard/Html/scripts/EditUserPage.js new file mode 100644 index 0000000000..0d362e5dea --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/EditUserPage.js @@ -0,0 +1,175 @@ +var EditUserPage = { + + onPageShow: function () { + Dashboard.showLoadingMsg(); + + var userId = getParameterByName("userId"); + + if (userId) { + $('#userProfileNavigation', this).show(); + } else { + $('#userProfileNavigation', this).hide(); + } + + var promise4 = ApiClient.getCultures(); + + var promise3 = ApiClient.getParentalRatings(); + + var promise1; + + if (!userId) { + + var deferred = $.Deferred(); + + deferred.resolveWith(null, [{ + Configuration: {} + }]); + + promise1 = deferred.promise(); + } else { + + promise1 = ApiClient.getUser(userId); + } + + var promise2 = Dashboard.getCurrentUser(); + + $.when(promise1, promise2, promise3, promise4).done(function (response1, response2, response3, response4) { + + EditUserPage.loadUser(response1[0] || response1, response2[0], response3[0], response4[0]); + + }); + }, + + loadUser: function (user, loggedInUser, allParentalRatings, allCultures) { + + var page = $($.mobile.activePage); + + EditUserPage.populateLanguages($('#selectAudioLanguage', page), allCultures); + EditUserPage.populateLanguages($('#selectSubtitleLanguage', page), allCultures); + EditUserPage.populateRatings(allParentalRatings, page); + + if (!loggedInUser.Configuration.IsAdministrator || user.Id == loggedInUser.Id) { + + $('#fldIsAdmin', page).hide(); + $('#fldMaxParentalRating', page).hide(); + } else { + $('#fldIsAdmin', page).show(); + $('#fldMaxParentalRating', page).show(); + } + + Dashboard.setPageTitle(user.Name || "Add User"); + + $('#txtUserName', page).val(user.Name); + + var ratingValue = ""; + + if (user.Configuration.MaxParentalRating) { + + for (var i = 0, length = allParentalRatings.length; i < length; i++) { + + var rating = allParentalRatings[i]; + + if (user.Configuration.MaxParentalRating >= rating.Value) { + ratingValue = rating.Value; + } + } + } + + $('#selectMaxParentalRating', page).val(ratingValue).selectmenu("refresh"); + + $('#selectAudioLanguage', page).val(user.Configuration.AudioLanguagePreference || "").selectmenu("refresh"); + $('#selectSubtitleLanguage', page).val(user.Configuration.SubtitleLanguagePreference || "").selectmenu("refresh"); + + $('#chkForcedSubtitlesOnly', page).checked(user.Configuration.UseForcedSubtitlesOnly || false).checkboxradio("refresh"); + $('#chkIsAdmin', page).checked(user.Configuration.IsAdministrator || false).checkboxradio("refresh"); + + Dashboard.hideLoadingMsg(); + }, + + populateLanguages: function (select, allCultures) { + + var html = ""; + + html += "<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); diff --git a/MediaBrowser.WebDashboard/Html/scripts/Extensions.js b/MediaBrowser.WebDashboard/Html/scripts/Extensions.js new file mode 100644 index 0000000000..dba43a7046 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/Extensions.js @@ -0,0 +1,333 @@ +// Array Remove - By John Resig (MIT Licensed) +Array.prototype.remove = function (from, to) { + var rest = this.slice((to || from) + 1 || this.length); + this.length = from < 0 ? this.length + from : from; + return this.push.apply(this, rest); +}; + +String.prototype.endsWith = function (suffix) { + return this.indexOf(suffix, this.length - suffix.length) !== -1; +}; + +$.fn.checked = function (value) { + if (value === true || value === false) { + // Set the value of the checkbox + return $(this).each(function () { + this.checked = value; + }); + } else { + // Return check state + return $(this).is(':checked'); + } +}; + +var WebNotifications = { + + show: function (data) { + if (window.webkitNotifications) { + if (!webkitNotifications.checkPermission()) { + var notif = webkitNotifications.createNotification(data.icon, data.title, data.body); + notif.show(); + + if (data.timeout) { + setTimeout(function () { + notif.cancel(); + }, data.timeout); + } + + return notif; + } else { + webkitNotifications.requestPermission(function () { + return WebNotifications.show(data); + }); + } + } + else if (window.Notification) { + if (Notification.permissionLevel() === "granted") { + var notif = new Notification(data.title, data); + notif.show(); + + if (data.timeout) { + setTimeout(function () { + notif.cancel(); + }, data.timeout); + } + + return notif; + } else if (Notification.permissionLevel() === "default") { + Notification.requestPermission(function () { + return WebNotifications.show(data); + }); + } + } + }, + + requestPermission: function () { + if (window.webkitNotifications) { + if (!webkitNotifications.checkPermission()) { + } else { + webkitNotifications.requestPermission(function () { + }); + } + } + else if (window.Notification) { + if (Notification.permissionLevel() === "granted") { + } else if (Notification.permissionLevel() === "default") { + Notification.requestPermission(function () { + }); + } + } + } +}; + +/* + * Javascript Humane Dates + * Copyright (c) 2008 Dean Landolt (deanlandolt.com) + * Re-write by Zach Leatherman (zachleat.com) + * + * Adopted from the John Resig's pretty.js + * at http://ejohn.org/blog/javascript-pretty-date + * and henrah's proposed modification + * at http://ejohn.org/blog/javascript-pretty-date/#comment-297458 + * + * Licensed under the MIT license. + */ + +function humane_date(date_str) { + var time_formats = [[90, 'a minute'], // 60*1.5 + [3600, 'minutes', 60], // 60*60, 60 + [5400, 'an hour'], // 60*60*1.5 + [86400, 'hours', 3600], // 60*60*24, 60*60 + [129600, 'a day'], // 60*60*24*1.5 + [604800, 'days', 86400], // 60*60*24*7, 60*60*24 + [907200, 'a week'], // 60*60*24*7*1.5 + [2628000, 'weeks', 604800], // 60*60*24*(365/12), 60*60*24*7 + [3942000, 'a month'], // 60*60*24*(365/12)*1.5 + [31536000, 'months', 2628000], // 60*60*24*365, 60*60*24*(365/12) + [47304000, 'a year'], // 60*60*24*365*1.5 + [3153600000, 'years', 31536000] // 60*60*24*365*100, 60*60*24*365 + ]; + + var dt = new Date; + var date = parseISO8601Date(date_str, true); + + var seconds = ((dt - date) / 1000); + var token = ' ago'; + var i = 0; + var format; + + if (seconds < 0) { + seconds = Math.abs(seconds); + token = ''; + } + + while (format = time_formats[i++]) { + if (seconds < format[0]) { + if (format.length == 2) { + return format[1] + token; + } else { + return Math.round(seconds / format[2]) + ' ' + format[1] + token; + } + } + } + + // overflow for centuries + if (seconds > 4730400000) + return Math.round(seconds / 4730400000) + ' centuries' + token; + + return date_str; +}; + +function humane_elapsed(firstDateStr, secondDateStr) { + var dt1 = new Date(firstDateStr); + var dt2 = new Date(secondDateStr); + var seconds = (dt2.getTime() - dt1.getTime()) / 1000; + var numdays = Math.floor((seconds % 31536000) / 86400); + var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600); + var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60); + var numseconds = Math.round((((seconds % 31536000) % 86400) % 3600) % 60); + + var elapsedStr = ''; + elapsedStr += numdays == 1 ? numdays + ' day ' : ''; + elapsedStr += numdays > 1 ? numdays + ' days ' : ''; + elapsedStr += numhours == 1 ? numhours + ' hour ' : ''; + elapsedStr += numhours > 1 ? numhours + ' hours ' : ''; + elapsedStr += numminutes == 1 ? numminutes + ' minute ' : ''; + elapsedStr += numminutes > 1 ? numminutes + ' minutes ' : ''; + elapsedStr += elapsedStr.length > 0 ? 'and ' : ''; + elapsedStr += numseconds == 1 ? numseconds + ' second' : ''; + elapsedStr += numseconds == 0 || numseconds > 1 ? numseconds + ' seconds' : ''; + + return elapsedStr; + +} + +function getParameterByName(name) { + name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); + var regexS = "[\\?&]" + name + "=([^&#]*)"; + var regex = new RegExp(regexS); + var results = regex.exec(window.location.search); + if (results == null) + return ""; + else + return decodeURIComponent(results[1].replace(/\+/g, " ")); +} + +function parseISO8601Date(s, toLocal) { + + // parenthese matches: + // year month day hours minutes seconds + // dotmilliseconds + // tzstring plusminus hours minutes + var re = /(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d+)?(Z|([+-])(\d\d):(\d\d))/; + + var d = []; + d = s.match(re); + + // "2010-12-07T11:00:00.000-09:00" parses to: + // ["2010-12-07T11:00:00.000-09:00", "2010", "12", "07", "11", + // "00", "00", ".000", "-09:00", "-", "09", "00"] + // "2010-12-07T11:00:00.000Z" parses to: + // ["2010-12-07T11:00:00.000Z", "2010", "12", "07", "11", + // "00", "00", ".000", "Z", undefined, undefined, undefined] + + if (!d) { + throw "Couldn't parse ISO 8601 date string '" + s + "'"; + } + + // parse strings, leading zeros into proper ints + var a = [1, 2, 3, 4, 5, 6, 10, 11]; + for (var i in a) { + d[a[i]] = parseInt(d[a[i]], 10); + } + d[7] = parseFloat(d[7]); + + // Date.UTC(year, month[, date[, hrs[, min[, sec[, ms]]]]]) + // note that month is 0-11, not 1-12 + // see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/UTC + var ms = Date.UTC(d[1], d[2] - 1, d[3], d[4], d[5], d[6]); + + // if there are milliseconds, add them + if (d[7] > 0) { + ms += Math.round(d[7] * 1000); + } + + // if there's a timezone, calculate it + if (d[8] != "Z" && d[10]) { + var offset = d[10] * 60 * 60 * 1000; + if (d[11]) { + offset += d[11] * 60 * 1000; + } + if (d[9] == "-") { + ms -= offset; + } else { + ms += offset; + } + } else if (!toLocal) { + ms += new Date().getTimezoneOffset() * 60000; + } + + return new Date(ms); +}; + + + +// jqm.page.params.js - version 0.1 +// Copyright (c) 2011, Kin Blas +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of the <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);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/IndexPage.js b/MediaBrowser.WebDashboard/Html/scripts/IndexPage.js new file mode 100644 index 0000000000..ee84e07de9 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/IndexPage.js @@ -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);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/ItemDetailPage.js b/MediaBrowser.WebDashboard/Html/scripts/ItemDetailPage.js new file mode 100644 index 0000000000..e5629f217f --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/ItemDetailPage.js @@ -0,0 +1,353 @@ +var ItemDetailPage = { + + onPageShow: function () { + + var id = getParameterByName('id'); + + Dashboard.showLoadingMsg(); + + ApiClient.getItem(Dashboard.getCurrentUserId(), id).done(ItemDetailPage.renderItem); + + }, + + renderItem: function (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.renderGallery(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(' ')); + + 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: '; + + for (var i = 0, length = item.Genres.length; i < length; i++) { + + if (i > 0) { + html += ' / '; + } + + 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: '; + + for (var i = 0, length = item.Studios.length; i < length; i++) { + + if (i > 0) { + html += ' / '; + } + + 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]); + }, + + 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); diff --git a/MediaBrowser.WebDashboard/Html/scripts/LogPage.js b/MediaBrowser.WebDashboard/Html/scripts/LogPage.js new file mode 100644 index 0000000000..133eb34fbb --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/LogPage.js @@ -0,0 +1,86 @@ +var LogPage = { + + onPageShow: function () { + + LogPage.startLine = 0; + + $('#logContents', this).html(''); + + $(document).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 () { + + $(document).off("websocketmessage", LogPage.onWebSocketMessage).off("websocketopen", LogPage.onWebSocketConnectionChange).off("websocketerror", LogPage.onWebSocketConnectionChange).off("websocketclose", LogPage.onWebSocketConnectionChange); + + LogPage.stopInterval(); + }, + + startInterval: function () { + + if (Dashboard.isWebSocketOpen()) { + Dashboard.sendWebSocketMessage("LogFileStart", "0,2000"); + } + }, + + stopInterval: function () { + + if (Dashboard.isWebSocketOpen()) { + Dashboard.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);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/LoginPage.js b/MediaBrowser.WebDashboard/Html/scripts/LoginPage.js new file mode 100644 index 0000000000..46e7d53cca --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/LoginPage.js @@ -0,0 +1,112 @@ +var LoginPage = { + + onPageShow: function () { + Dashboard.showLoadingMsg(); + + ApiClient.getAllUsers().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(); + + 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;' class='userItem'>"; + } else { + html += "<a id='" + linkId + "' data-userid='" + user.Id + "' data-username='" + user.Name + "' href='#' onclick='LoginPage.authenticateUserLink(this);' class='userItem'>"; + } + + if (user.PrimaryImageTag) { + + var imgUrl = ApiClient.getUserImageUrl(user.Id, { + width: 500, + tag: user.PrimaryImageTag, + type: "Primary" + }); + + html += '<img class="userItemImage" src="' + imgUrl + '" />'; + } else { + html += '<img class="userItemImage" src="css/images/logindefault.png" style="background:' + background + ';" />'; + } + + html += '<div class="userItemContent" style="background:' + background + ';">'; + + html += '<div class="userItemContentInner">'; + html += '<p class="userItemHeader">' + user.Name + '</p>'; + html += '<p>' + LoginPage.getLastSeenText(user.LastActivityDate) + '</p>'; + html += '</div>'; + + html += '</div>'; + html += '</a>'; + } + + $('#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); diff --git a/MediaBrowser.WebDashboard/Html/scripts/MediaLibraryPage.js b/MediaBrowser.WebDashboard/Html/scripts/MediaLibraryPage.js new file mode 100644 index 0000000000..4f4d119d83 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/MediaLibraryPage.js @@ -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);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/MediaPlayer.js b/MediaBrowser.WebDashboard/Html/scripts/MediaPlayer.js new file mode 100644 index 0000000000..bf3733ffdc --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/MediaPlayer.js @@ -0,0 +1,170 @@ +var MediaPlayer = { + + canPlay: function (item) { + + if (item.MediaType === "Video") { + + var media = document.createElement('video'); + + if (media.canPlayType) { + + return media.canPlayType('video/mp2t').replace(/no/, '') || media.canPlayType('video/webm').replace(/no/, '') || media.canPlayType('video/ogv').replace(/no/, ''); + } + + return false; + } + + if (item.MediaType === "Audio") { + + var media = document.createElement('audio'); + + 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 = { + id: item.Id, + audioChannels: 2, + audioBitrate: 128000 + }; + + var mp3Url = ApiClient.getUrl('audio.mp3', $.extend({}, baseParams, { + audioCodec: 'mp3' + })); + + var aacUrl = ApiClient.getUrl('audio.aac', $.extend({}, baseParams, { + audioCodec: 'aac' + })); + + var webmUrl = ApiClient.getUrl('audio.webma', $.extend({}, baseParams, { + audioCodec: 'Vorbis' + })); + + var oggUrl = ApiClient.getUrl('audio.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]; + + var screenWidth = Math.max(screen.height, screen.width); + var screenHeight = Math.min(screen.height, screen.width); + + var baseParams = { + id: item.Id, + audioChannels: 2, + audioBitrate: 128000, + videoBitrate: 500000, + maxWidth: screenWidth, + maxHeight: screenHeight + }; + + var tsVideoUrl = ApiClient.getUrl('video.ts', $.extend({}, baseParams, { + videoCodec: 'h264', + audioCodec: 'aac' + })); + + var webmVideoUrl = ApiClient.getUrl('video.webm', $.extend({}, baseParams, { + videoCodec: 'vpx', + audioCodec: 'Vorbis' + })); + + var ogvVideoUrl = ApiClient.getUrl('video.ogv', $.extend({}, baseParams, { + videoCodec: 'theora', + audioCodec: 'Vorbis' + })); + + var html = ''; + html += '<video class="itemVideo" preload="none" controls autoplay>'; + html += '<source type=\'video/mp2t; codecs="h264, aac"\' src="' + tsVideoUrl + '">'; + html += '<source type=\'video/webm; codecs="vp8, vorbis"\' src="' + webmVideoUrl + '">'; + html += '<source type=\'video/ogg; codecs="theora, vorbis"\' 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; + } +};
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/MetadataConfigurationPage.js b/MediaBrowser.WebDashboard/Html/scripts/MetadataConfigurationPage.js new file mode 100644 index 0000000000..e68940b832 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/MetadataConfigurationPage.js @@ -0,0 +1,103 @@ +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"); + }, + + onSubmit: function () { + Dashboard.showLoadingMsg(); + + 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).done(Dashboard.processServerConfigurationUpdateResult); + }); + + // Disable default form submission + return false; + } +}; + +$(document).on('pageshow', "#metadataConfigurationPage", MetadataConfigurationPage.onPageShow);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/MetadataImagesPage.js b/MediaBrowser.WebDashboard/Html/scripts/MetadataImagesPage.js new file mode 100644 index 0000000000..c9f2523f7a --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/MetadataImagesPage.js @@ -0,0 +1,74 @@ +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.DownloadMovieArt).checkboxradio("refresh"); + $('#chkDownloadMovieBanner', page).checked(config.DownloadMovieBanner).checkboxradio("refresh"); + $('#chkDownloadMovieDisc', page).checked(config.DownloadMovieDisc).checkboxradio("refresh"); + $('#chkDownloadMovieLogo', page).checked(config.DownloadMovieLogo).checkboxradio("refresh"); + $('#chkDownloadMovieThumb', page).checked(config.DownloadMovieThumb).checkboxradio("refresh"); + $('#chKDownloadTVArt', page).checked(config.DownloadTVArt).checkboxradio("refresh"); + $('#chkDownloadTVBanner', page).checked(config.DownloadTVBanner).checkboxradio("refresh"); + $('#chkDownloadTVLogo', page).checked(config.DownloadTVLogo).checkboxradio("refresh"); + $('#chkDownloadTVThumb', page).checked(config.DownloadTVThumb).checkboxradio("refresh"); + $('#chkDownloadSeasonBanner', page).checked(config.DownloadTVSeasonBanner).checkboxradio("refresh"); + $('#chkDownloadSeasonThumb', page).checked(config.DownloadTVSeasonThumb).checkboxradio("refresh"); + $('#chkDownloadSeasonBackdrops', page).checked(config.DownloadTVSeasonBackdrops).checkboxradio("refresh"); + + Dashboard.hideLoadingMsg(); + }, + + onSubmit: function () { + Dashboard.showLoadingMsg(); + + 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.DownloadMovieArt = $('#chkDownloadMovieArt', form).checked(); + config.DownloadMovieBanner = $('#chkDownloadMovieBanner', form).checked(); + config.DownloadMovieDisc = $('#chkDownloadMovieDisc', form).checked(); + config.DownloadMovieLogo = $('#chkDownloadMovieLogo', form).checked(); + config.DownloadMovieThumb = $('#chkDownloadMovieThumb', form).checked(); + config.DownloadTVArt = $('#chKDownloadTVArt', form).checked(); + config.DownloadTVBanner = $('#chkDownloadTVBanner', form).checked(); + config.DownloadTVLogo = $('#chkDownloadTVLogo', form).checked(); + config.DownloadTVThumb = $('#chkDownloadTVThumb', form).checked(); + config.DownloadTVSeasonBanner = $('#chkDownloadSeasonBanner', form).checked(); + config.DownloadTVSeasonThumb = $('#chkDownloadSeasonThumb', form).checked(); + config.DownloadTVSeasonBackdrops = $('#chkDownloadSeasonBackdrops', form).checked(); + + ApiClient.updateServerConfiguration(config).done(Dashboard.processServerConfigurationUpdateResult); + }); + + // Disable default form submission + return false; + } +}; + +$(document).on('pageshow', "#metadataImagesConfigurationPage", MetadataImagesPage.onPageShow);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/PluginCatalogPage.js b/MediaBrowser.WebDashboard/Html/scripts/PluginCatalogPage.js new file mode 100644 index 0000000000..51034a0337 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/PluginCatalogPage.js @@ -0,0 +1,80 @@ +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) { + html += "<div class='premiumBanner'><img src='css/images/premiumflag.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]; + + if (installedPlugin) { + + html += plugin.name + " (Installed)"; + } else { + html += plugin.name; + } + + html += "</div>"; + + html += "</a></div>"; + + } + + $('#pluginTiles', page).html(html); + + Dashboard.hideLoadingMsg(); + } +}; + +$(document).on('pageshow', "#pluginCatalogPage", PluginCatalogPage.onPageShow);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/PluginUpdatesPage.js b/MediaBrowser.WebDashboard/Html/scripts/PluginUpdatesPage.js new file mode 100644 index 0000000000..4edb08602b --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/PluginUpdatesPage.js @@ -0,0 +1,109 @@ +var PluginUpdatesPage = { + + onPageShow: function () { + + Dashboard.showLoadingMsg(); + + $('.liPluginUpdate', this).remove(); + + ApiClient.getInstalledPlugins().done(PluginUpdatesPage.loadPlugins); + + }, + + loadPlugins: function (plugins) { + + plugins = plugins.filter(function (p) { + + return !p.IsCorePlugin; + }); + + 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-uniqueid='" + plugin.UniqueId + "' 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-uniqueid='" + plugin.UniqueId + "' 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-uniqueid'); + + 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-uniqueid'); + + 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);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/PluginsPage.js b/MediaBrowser.WebDashboard/Html/scripts/PluginsPage.js new file mode 100644 index 0000000000..f7e05e4bac --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/PluginsPage.js @@ -0,0 +1,92 @@ +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.IsCorePlugin.toString() + plugin1.Name) > (plugin2.IsCorePlugin.toString() + plugin2.Name) ? 1 : -1; + + }); + + var html = ""; + + for (var i = 0, length = plugins.length; i < length; i++) { + + var plugin = plugins[i]; + + if (plugin.IsCorePlugin) { + continue; + } + + var configPage = $.grep(pluginConfigurationPages, function (pluginConfigurationPage) { + return pluginConfigurationPage.OwnerPluginName == plugin.Name; + })[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>"; + + if (!plugin.IsCorePlugin) { + html += "<a data-uniqueid='" + plugin.UniqueId + "' 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-uniqueid'); + + 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);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/ScheduledTaskPage.js b/MediaBrowser.WebDashboard/Html/scripts/ScheduledTaskPage.js new file mode 100644 index 0000000000..e7ea33f809 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/ScheduledTaskPage.js @@ -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);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/ScheduledTasksPage.js b/MediaBrowser.WebDashboard/Html/scripts/ScheduledTasksPage.js new file mode 100644 index 0000000000..d822db722d --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/ScheduledTasksPage.js @@ -0,0 +1,170 @@ +var ScheduledTasksPage = { + + onPageShow: function () { + + Dashboard.showLoadingMsg(); + + ScheduledTasksPage.reloadList(true); + + $(document).on("websocketmessage", ScheduledTasksPage.onWebSocketMessage).on("websocketopen", ScheduledTasksPage.onWebSocketConnectionChange).on("websocketerror", ScheduledTasksPage.onWebSocketConnectionChange).on("websocketclose", ScheduledTasksPage.onWebSocketConnectionChange); + }, + + onPageHide: function () { + $(document).off("websocketmessage", ScheduledTasksPage.onWebSocketMessage).off("websocketopen", ScheduledTasksPage.onWebSocketConnectionChange).off("websocketerror", ScheduledTasksPage.onWebSocketConnectionChange).off("websocketclose", ScheduledTasksPage.onWebSocketConnectionChange); + ScheduledTasksPage.stopInterval(); + }, + + startInterval: function () { + + if (Dashboard.isWebSocketOpen()) { + Dashboard.sendWebSocketMessage("ScheduledTasksInfoStart", "1500,1500"); + } + }, + + stopInterval: function () { + + if (Dashboard.isWebSocketOpen()) { + Dashboard.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 run " + 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 = task.CurrentProgress || { PercentComplete: 0 }; + progress = Math.round(progress.PercentComplete); + + 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);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/SupporterKeyPage.js b/MediaBrowser.WebDashboard/Html/scripts/SupporterKeyPage.js new file mode 100644 index 0000000000..50da44331d --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/SupporterKeyPage.js @@ -0,0 +1,79 @@ +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 + }; + + var url = ApiClient.getUrl("Plugins/SecurityInfo"); + console.log(url); + $.post(url, JSON.stringify(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); diff --git a/MediaBrowser.WebDashboard/Html/scripts/SupporterPage.js b/MediaBrowser.WebDashboard/Html/scripts/SupporterPage.js new file mode 100644 index 0000000000..2a599f2592 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/SupporterPage.js @@ -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); diff --git a/MediaBrowser.WebDashboard/Html/scripts/UpdatePasswordPage.js b/MediaBrowser.WebDashboard/Html/scripts/UpdatePasswordPage.js new file mode 100644 index 0000000000..9c3a009b23 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/UpdatePasswordPage.js @@ -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);
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/UserImagePage.js b/MediaBrowser.WebDashboard/Html/scripts/UserImagePage.js new file mode 100644 index 0000000000..58dadc6f8a --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/UserImagePage.js @@ -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); diff --git a/MediaBrowser.WebDashboard/Html/scripts/UserProfilesPage.js b/MediaBrowser.WebDashboard/Html/scripts/UserProfilesPage.js new file mode 100644 index 0000000000..b36962a5c4 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/UserProfilesPage.js @@ -0,0 +1,76 @@ +var UserProfilesPage = { + onPageShow: function () { + + UserProfilesPage.loadPageData(); + }, + + loadPageData: function () { + + Dashboard.showLoadingMsg(); + ApiClient.getAllUsers().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); diff --git a/MediaBrowser.WebDashboard/Html/scripts/WizardStartPage.js b/MediaBrowser.WebDashboard/Html/scripts/WizardStartPage.js new file mode 100644 index 0000000000..97c09d2ab6 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/WizardStartPage.js @@ -0,0 +1,17 @@ +var WizardStartPage = { + + gotoNextPage: function () { + + ApiClient.getAllUsers().done(function (users) { + + if (users.length > 1) { + + Dashboard.navigate('wizardLibrary.html'); + + } else { + Dashboard.navigate('wizardUser.html'); + } + }); + + } +};
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/scripts/WizardUserPage.js b/MediaBrowser.WebDashboard/Html/scripts/WizardUserPage.js new file mode 100644 index 0000000000..decc6c3a39 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/WizardUserPage.js @@ -0,0 +1,59 @@ +var WizardUserPage = { + + onPageShow: function () { + + Dashboard.showLoadingMsg(); + + var page = this; + + ApiClient.getAllUsers().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.getAllUsers().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); diff --git a/MediaBrowser.WebDashboard/Html/scripts/site.js b/MediaBrowser.WebDashboard/Html/scripts/site.js new file mode 100644 index 0000000000..d358b974ef --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/scripts/site.js @@ -0,0 +1,1185 @@ +$.ajaxSetup({ + crossDomain: true, + + error: function (event, jqxhr, settings, exception) { + Dashboard.hideLoadingMsg(); + + if (!Dashboard.suppressAjaxErrors) { + setTimeout(function () { + + + var msg = event.getResponseHeader("X-Application-Error-Code") || Dashboard.defaultErrorMessage; + + Dashboard.showError(msg); + }, 500); + } + } +}); + +$.support.cors = true; + +$(document).one('click', WebNotifications.requestPermission); + +var Dashboard = { + jQueryMobileInit: function () { + + //$.mobile.defaultPageTransition = 'slide'; + + // Page + //$.mobile.page.prototype.options.theme = "a"; + //$.mobile.page.prototype.options.headerTheme = "a"; + //$.mobile.page.prototype.options.contentTheme = "a"; + //$.mobile.page.prototype.options.footerTheme = "a"; + + //$.mobile.button.prototype.options.theme = "c"; + $.mobile.listview.prototype.options.dividerTheme = "b"; + + $.mobile.popup.prototype.options.theme = "c"; + //$.mobile.collapsible.prototype.options.contentTheme = "a"; + }, + + getCurrentUser: function () { + + if (!Dashboard.getUserPromise) { + Dashboard.getUserPromise = ApiClient.getUser(Dashboard.getCurrentUserId()).fail(Dashboard.logout); + } + + return Dashboard.getUserPromise; + }, + + validateCurrentUser: function () { + Dashboard.getUserPromise = null; + + if (Dashboard.getCurrentUserId()) { + Dashboard.getCurrentUser(); + } + + // Re-render the header + $('.header').remove(); + Dashboard.ensureHeader($.mobile.activePage); + }, + + getCurrentUserId: function () { + + var userId = localStorage.getItem("userId"); + + if (!userId) { + var autoLoginUserId = getParameterByName('u'); + + if (autoLoginUserId) { + userId = autoLoginUserId; + localStorage.setItem("userId", userId); + } + } + + return userId; + }, + + setCurrentUser: function (userId) { + localStorage.setItem("userId", userId); + Dashboard.getUserPromise = null; + }, + + logout: function () { + localStorage.removeItem("userId"); + Dashboard.getUserPromise = null; + window.location = "login.html"; + }, + + showError: function (message) { + + $.mobile.loading('show', { + theme: "e", + text: message, + textonly: true, + textVisible: true + }); + + setTimeout(function () { + $.mobile.loading('hide'); + }, 2000); + }, + + alert: function (message) { + + $.mobile.loading('show', { + theme: "e", + text: message, + textonly: true, + textVisible: true + }); + + setTimeout(function () { + $.mobile.loading('hide'); + }, 2000); + }, + + updateSystemInfo: function (info) { + + var isFirstLoad = !Dashboard.lastSystemInfo; + + Dashboard.lastSystemInfo = info; + Dashboard.ensureWebSocket(info); + + if (!Dashboard.initialServerVersion) { + Dashboard.initialServerVersion = info.Version; + } + + if (info.HasPendingRestart) { + + Dashboard.hideDashboardVersionWarning(); + Dashboard.showServerRestartWarning(); + + } else { + + Dashboard.hideServerRestartWarning(); + + if (Dashboard.initialServerVersion != info.Version) { + + Dashboard.showDashboardVersionWarning(); + } + } + + if (isFirstLoad) { + Dashboard.showFailedAssemblies(info.FailedPluginAssemblies); + } + + Dashboard.showInProgressInstallations(info.InProgressInstallations); + }, + + showFailedAssemblies: function (failedAssemblies) { + + for (var i = 0, length = failedAssemblies.length; i < length; i++) { + + var assembly = failedAssemblies[i]; + + var html = '<img src="css/images/notifications/error.png" class="notificationIcon" />'; + + var index = assembly.lastIndexOf('\\'); + + if (index != -1) { + assembly = assembly.substring(index + 1); + } + + html += '<span>'; + html += assembly + " failed to load."; + html += '</span>'; + + Dashboard.showFooterNotification({ html: html }); + + } + }, + + showInProgressInstallations: function (installations) { + + installations = installations || []; + + for (var i = 0, length = installations.length; i < length; i++) { + + var installation = installations[i]; + + var percent = installation.PercentComplete || 0; + + if (percent < 100) { + Dashboard.showPackageInstallNotification(installation, "progress"); + } + } + + if (installations.length) { + + Dashboard.ensureInstallRefreshInterval(); + } else { + Dashboard.stopInstallRefreshInterval(); + } + }, + + ensureInstallRefreshInterval: function () { + + if (!Dashboard.installRefreshInterval) { + + if (Dashboard.isWebSocketOpen()) { + Dashboard.sendWebSocketMessage("SystemInfoStart", "0,350"); + } + Dashboard.installRefreshInterval = 1; + } + }, + + stopInstallRefreshInterval: function () { + + if (Dashboard.installRefreshInterval) { + if (Dashboard.isWebSocketOpen()) { + Dashboard.sendWebSocketMessage("SystemInfoStop"); + } + Dashboard.installRefreshInterval = null; + } + }, + + cancelInstallation: function (id) { + + ApiClient.cancelPackageInstallation(id).always(Dashboard.refreshSystemInfoFromServer); + + }, + + showServerRestartWarning: function () { + + var html = '<span style="margin-right: 1em;">Please restart Media Browser Server to finish updating.</span>'; + html += '<button type="button" data-icon="refresh" onclick="Dashboard.restartServer();" data-theme="b" data-inline="true" data-mini="true">Restart Server</button>'; + + Dashboard.showFooterNotification({ id: "serverRestartWarning", html: html, forceShow: true, allowHide: false }); + }, + + hideServerRestartWarning: function () { + + $('#serverRestartWarning').remove(); + }, + + showDashboardVersionWarning: function () { + + var html = '<span style="margin-right: 1em;">Please refresh this page to receive new updates from the server.</span>'; + html += '<button type="button" data-icon="refresh" onclick="Dashboard.reloadPage();" data-theme="b" data-inline="true" data-mini="true">Refresh Page</button>'; + + Dashboard.showFooterNotification({ id: "dashboardVersionWarning", html: html, forceShow: true, allowHide: false }); + }, + + reloadPage: function () { + + window.location.href = window.location.href; + }, + + hideDashboardVersionWarning: function () { + + $('#dashboardVersionWarning').remove(); + }, + + showFooterNotification: function (options) { + + var removeOnHide = !options.id; + + options.id = options.id || "notification" + new Date().getTime() + parseInt(Math.random()); + + var parentElem = $('#footerNotifications'); + + var elem = $('#' + options.id, parentElem); + + if (!elem.length) { + elem = $('<p id="' + options.id + '" class="footerNotification"></p>').appendTo(parentElem); + } + + var onclick = removeOnHide ? "$(\"#" + options.id + "\").remove();" : "$(\"#" + options.id + "\").hide();"; + + if (options.allowHide !== false) { + options.html += "<span style='margin-left: 1em;'><button type='button' onclick='" + onclick + "' data-icon='delete' data-iconpos='notext' data-mini='true' data-inline='true' data-theme='a'>Hide</button></span>"; + } + + if (options.forceShow) { + elem.show(); + } + + elem.html(options.html).trigger('create'); + + if (options.timeout) { + + setTimeout(function () { + + if (removeOnHide) { + elem.remove(); + } else { + elem.hide(); + } + + }, options.timeout); + } + }, + + getConfigurationPageUrl: function (name) { + return "ConfigurationPage?name=" + encodeURIComponent(name); + }, + + navigate: function (url, preserveQueryString) { + + var queryString = window.location.search; + if (preserveQueryString && queryString) { + url += queryString; + } + $.mobile.changePage(url); + }, + + showLoadingMsg: function () { + $.mobile.showPageLoadingMsg(); + }, + + hideLoadingMsg: function () { + $.mobile.hidePageLoadingMsg(); + }, + + processPluginConfigurationUpdateResult: function () { + + Dashboard.hideLoadingMsg(); + + Dashboard.alert("Settings saved."); + }, + + defaultErrorMessage: "There was an error processing the request.", + + processServerConfigurationUpdateResult: function (result) { + + Dashboard.hideLoadingMsg(); + + Dashboard.alert("Settings saved."); + }, + + confirm: function (message, title, callback) { + + $('#confirmFlyout').popup("close").remove(); + + var html = '<div data-role="popup" id="confirmFlyout" style="max-width:500px;" class="ui-corner-all">'; + + html += '<div class="ui-corner-top ui-bar-a" style="text-align:center;">'; + html += '<h3>' + title + '</h3>'; + html += '</div>'; + + html += '<div data-role="content" class="ui-corner-bottom ui-content">'; + + html += '<div style="padding: 1em .25em;margin: 0;">'; + html += message; + html += '</div>'; + + html += '<p><button type="button" data-icon="ok" onclick="$(\'#confirmFlyout\')[0].confirm=true;$(\'#confirmFlyout\').popup(\'close\');" data-theme="b">Ok</button></p>'; + html += '<p><button type="button" data-icon="delete" onclick="$(\'#confirmFlyout\').popup(\'close\');" data-theme="a">Cancel</button></p>'; + html += '</div>'; + + html += '</div>'; + + $(document.body).append(html); + + $('#confirmFlyout').popup().trigger('create').popup("open").on("popupafterclose", function () { + + if (callback) { + callback(this.confirm == true); + } + + $(this).off("popupafterclose").remove(); + }); + }, + + refreshSystemInfoFromServer: function () { + ApiClient.getSystemInfo().done(function (info) { + + Dashboard.updateSystemInfo(info); + }); + }, + + restartServer: function () { + + Dashboard.suppressAjaxErrors = true; + Dashboard.showLoadingMsg(); + + ApiClient.performPendingRestart().done(function () { + + setTimeout(function () { + Dashboard.reloadPageWhenServerAvailable(); + }, 500); + + }).fail(function () { + Dashboard.suppressAjaxErrors = false; + }); + }, + + reloadPageWhenServerAvailable: function (retryCount) { + + ApiClient.getSystemInfo().done(function () { + Dashboard.reloadPage(); + + }).fail(function () { + setTimeout(function () { + + retryCount = retryCount || 0; + retryCount++; + + if (retryCount < 10) { + Dashboard.reloadPageWhenServerAvailable(retryCount); + } else { + Dashboard.suppressAjaxErrors = false; + } + }, 500); + }); + }, + + getPosterViewHtml: function (options) { + + var html = ""; + + for (var i = 0, length = options.items.length; i < length; i++) { + var item = options.items[i]; + + var hasPrimaryImage = item.ImageTags && item.ImageTags.Primary; + + var href = item.IsFolder ? "#" : "itemDetails.html?id=" + item.Id; + + html += "<div class='posterViewItem'><a href='" + href + "'>"; + + if (options.preferBackdrop && item.BackdropImageTags && item.BackdropImageTags.length) { + html += "<img src='" + ApiClient.getImageUrl(item.Id, { + type: "Backdrop", + height: 198, + width: 352, + tag: item.BackdropImageTags[0] + }) + "' />"; + } else if (hasPrimaryImage) { + html += "<img src='" + ApiClient.getImageUrl(item.Id, { + type: "Primary", + height: 300, + tag: item.ImageTags.Primary + }) + "' />"; + } + else if (item.BackdropImageTags && item.BackdropImageTags.length) { + html += "<img src='" + ApiClient.getImageUrl(item.Id, { + type: "Backdrop", + height: 198, + width: 352, + tag: item.BackdropImageTags[0] + }) + "' />"; + } else { + html += "<img style='background:" + Dashboard.getRandomMetroColor() + ";' src='css/images/defaultCollectionImage.png' />"; + } + + if (options.showTitle || !hasPrimaryImage || (item.Type !== 'Movie' && item.Type !== 'Series' && item.Type !== 'Season')) { + html += "<div class='posterViewItemText'>" + item.Name + "</div>"; + } + + html += "</a></div>"; + } + + return html; + }, + + showUserFlyout: function () { + + Dashboard.getCurrentUser().done(function (user) { + + var html = '<div data-role="popup" id="userFlyout" style="max-width:400px;margin-top:50px;margin-right:20px;" class="ui-corner-all" data-position-to=".btnCurrentUser:visible">'; + + html += '<a href="#" data-rel="back" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close</a>'; + + html += '<div class="ui-corner-top ui-bar-a" style="text-align:center;">'; + html += '<h3>' + user.Name + '</h3>'; + html += '</div>'; + + html += '<div data-role="content" class="ui-corner-bottom ui-content">'; + + html += '<p style="text-align:center;">'; + + var imageUrl = user.PrimaryImageTag ? ApiClient.getUserImageUrl(user.Id, { + + height: 400, + tag: user.PrimaryImageTag, + type: "Primary" + + }) : "css/images/userFlyoutDefault.png"; + + html += '<img style="max-height:125px;max-width:200px;" src="' + imageUrl + '" />'; + html += '</p>'; + + html += '<p><button type="button" onclick="Dashboard.navigate(\'editUser.html?userId=' + user.Id + '\');" data-icon="user">View Profile</button></p>'; + html += '<p><button type="button" onclick="Dashboard.logout();" data-icon="lock">Sign Out</button></p>'; + html += '</div>'; + + html += '</div>'; + + $(document.body).append(html); + + $('#userFlyout').popup().trigger('create').popup("open").on("popupafterclose", function () { + + $(this).off("popupafterclose").remove(); + }); + }); + }, + + selectDirectory: function (options) { + + options = options || {}; + + options.header = options.header || "Select Media Path"; + + var html = '<div data-role="popup" id="popupDirectoryPicker" class="ui-corner-all popup">'; + + html += '<div class="ui-corner-top ui-bar-a" style="text-align: center; padding: 0 20px;">'; + html += '<h3>' + options.header + '</h3>'; + html += '</div>'; + + html += '<div data-role="content" class="ui-corner-bottom ui-content">'; + html += '<form>'; + html += '<p>Browse to or enter the folder containing the media. Network paths (UNC) are recommended for optimal playback performance.</p>'; + + html += '<div data-role="fieldcontain" style="margin:0;">'; + html += '<label for="txtDirectoryPickerPath">Current Folder:</label>'; + html += '<input id="txtDirectoryPickerPath" name="txtDirectoryPickerPath" type="text" onchange="Dashboard.refreshDirectoryBrowser(this.value);" required="required" style="font-weight:bold;" />'; + html += '</div>'; + + html += '<div style="height: 300px; overflow-y: auto;">'; + html += '<ul id="ulDirectoryPickerList" data-role="listview" data-inset="true" data-auto-enhanced="false"></ul>'; + html += '</div>'; + + html += '<p>'; + html += '<button type="submit" data-theme="b" data-icon="ok">OK</button>'; + html += '<button type="button" data-icon="delete" onclick="$(this).parents(\'.popup\').popup(\'close\');">Cancel</button>'; + html += '</p>'; + html += '</form>'; + html += '</div>'; + html += '</div>'; + + $($.mobile.activePage).append(html); + + var popup = $('#popupDirectoryPicker').popup().trigger('create').popup("open").on("popupafterclose", function () { + + $('form', this).off("submit"); + $(this).off("click").off("popupafterclose").remove(); + + }).on("click", ".lnkDirectory", function () { + + var path = this.getAttribute('data-path'); + + Dashboard.refreshDirectoryBrowser(path); + }); + + var txtCurrentPath = $('#txtDirectoryPickerPath', popup); + + if (options.path) { + txtCurrentPath.val(options.path); + } + + $('form', popup).on('submit', function () { + + if (options.callback) { + options.callback($('#txtDirectoryPickerPath', this).val()); + } + + return false; + }); + + Dashboard.refreshDirectoryBrowser(txtCurrentPath.val()); + }, + + refreshDirectoryBrowser: function (path) { + var page = $.mobile.activePage; + + Dashboard.showLoadingMsg(); + + var promise; + + if (path === "Network") { + promise = ApiClient.getNetworkComputers(); + } + else if (path) { + promise = ApiClient.getDirectoryContents(path, { includeDirectories: true }); + } else { + promise = ApiClient.getDrives(); + } + + promise.done(function (folders) { + + $('#txtDirectoryPickerPath', page).val(path || ""); + + var html = ''; + + if (path) { + + var parentPath = path; + + if (parentPath.endsWith('\\')) { + parentPath = parentPath.substring(0, parentPath.length - 1); + } + + var lastIndex = parentPath.lastIndexOf('\\'); + parentPath = lastIndex == -1 ? "" : parentPath.substring(0, lastIndex); + + if (parentPath.endsWith(':')) { + parentPath += "\\"; + } + + if (parentPath == '\\') { + parentPath = "Network"; + } + + html += '<li><a class="lnkDirectory" data-path="' + parentPath + '" href="#">..</a></li>'; + } + + for (var i = 0, length = folders.length; i < length; i++) { + + var folder = folders[i]; + + html += '<li><a class="lnkDirectory" data-path="' + folder.Path + '" href="#">' + folder.Name + '</a></li>'; + } + + if (!path) { + html += '<li><a class="lnkDirectory" data-path="Network" href="#">Network</a></li>'; + } + + $('#ulDirectoryPickerList', page).html(html).listview('refresh'); + + Dashboard.hideLoadingMsg(); + + }).fail(function () { + + $('#txtDirectoryPickerPath', page).val(""); + $('#ulDirectoryPickerList', page).html('').listview('refresh'); + + Dashboard.hideLoadingMsg(); + }); + }, + + getPluginSecurityInfo: function () { + + if (!Dashboard.getPluginSecurityInfoPromise) { + Dashboard.getPluginSecurityInfoPromise = ApiClient.getPluginSecurityInfo(); + } + + return Dashboard.getPluginSecurityInfoPromise; + }, + + resetPluginSecurityInfo: function () { + Dashboard.getPluginSecurityInfoPromise = null; + }, + + ensureHeader: function (page) { + + if (!$('.header', page).length) { + + var isLoggedIn = Dashboard.getCurrentUserId(); + + if (isLoggedIn) { + + var promise1 = Dashboard.getCurrentUser(); + var promise2 = Dashboard.getPluginSecurityInfo(); + + $.when(promise1, promise2).done(function (response1, response2) { + + Dashboard.renderHeader(page, response1[0], response2[0]); + }); + + } else { + + Dashboard.renderHeader(page); + } + } + }, + + renderHeader: function (page, user, pluginSecurityInfo) { + + var headerHtml = ''; + headerHtml += '<div class="header">'; + + var isLibraryPage = page.hasClass('libraryPage'); + + headerHtml += '<a class="logo" href="index.html">'; + + if (page.hasClass('standalonePage')) { + + headerHtml += '<img class="imgLogo" src="css/images/mblogoblackfull.png" />'; + } + else if (isLibraryPage) { + + headerHtml += '<img class="imgLogo" src="css/images/mblogowhitefull.png" />'; + } + headerHtml += '</a>'; + + var imageColor = isLibraryPage ? "White" : "Black"; + + if (user && !page.hasClass('wizardPage')) { + headerHtml += '<div class="headerButtons">'; + headerHtml += '<a class="imageLink btnCurrentUser" href="#" onclick="Dashboard.showUserFlyout();"><span class="currentUsername">' + user.Name + '</span>'; + + if (user.PrimaryImageTag) { + + var url = ApiClient.getUserImageUrl(user.Id, { + width: 225, + tag: user.PrimaryImageTag, + type: "Primary" + }); + + headerHtml += '<img src="' + url + '" />'; + } else { + headerHtml += '<img src="css/images/currentUserDefault' + imageColor + '.png" />'; + } + headerHtml += '</a>'; + + if (pluginSecurityInfo.IsMBSupporter) { + headerHtml += '<a class="imageLink" href="supporter.html"><img src="css/images/suppbadge.png" /></a>'; + } + if (user.Configuration.IsAdministrator) { + headerHtml += '<a class="imageLink" href="dashboard.html"><img src="css/images/tools' + imageColor + '.png" /></a>'; + } + + headerHtml += '</div>'; + } + + headerHtml += '</div>'; + page.prepend(headerHtml); + }, + + ensureToolsMenu: function (page) { + + if (!page.hasClass('type-interior')) { + return; + } + + var sidebar = $('.toolsSidebar', page); + + if (!sidebar.length) { + + var html = '<div class="content-secondary ui-bar-a toolsSidebar">'; + + html += '<h1><a href="index.html" class="imageLink" style="margin-left: 0;margin-right: 20px;"> <img src="css/images/home.png" /></a>Tools</h1>'; + + html += '<div class="sidebarLinks">'; + + var links = Dashboard.getToolsMenuLinks(page); + + for (var i = 0, length = links.length; i < length; i++) { + + var link = links[i]; + + if (link.href) { + + if (link.selected) { + html += '<a class="selectedSidebarLink" href="' + link.href + '">' + link.name + '</a>'; + } else { + html += '<a href="' + link.href + '">' + link.name + '</a>'; + } + + } + } + + // collapsible + html += '</div>'; + + // content-secondary + html += '</div>'; + + $(page).append(html); + } + }, + + getToolsMenuLinks: function (page) { + + var pageElem = page[0]; + + return [{ + name: "Dashboard", + href: "dashboard.html", + selected: pageElem.id == "dashboardPage" + }, { + name: "Media Library", + href: "library.html", + selected: pageElem.id == "mediaLibraryPage" + }, { + name: "Metadata", + href: "metadata.html", + selected: pageElem.id == "metadataConfigurationPage" || pageElem.id == "advancedMetadataConfigurationPage" || pageElem.id == "metadataImagesConfigurationPage" + }, { + name: "Plugins", + href: "plugins.html", + selected: page.hasClass("pluginConfigurationPage") + }, { + name: "User Profiles", + href: "userProfiles.html", + selected: page.hasClass("userProfilesConfigurationPage") + }, { + name: "Display Settings", + href: "uiSettings.html", + selected: pageElem.id == "displaySettingsPage" + }, { + name: "Advanced", + href: "advanced.html", + selected: pageElem.id == "advancedConfigurationPage" + }, { + name: "Scheduled Tasks", + href: "scheduledTasks.html", + selected: pageElem.id == "scheduledTasksPage" || pageElem.id == "scheduledTaskPage" + }, { + name: "Help", + href: "support.html", + selected: pageElem.id == "supportPage" || pageElem.id == "logPage" || pageElem.id == "supporterPage" || pageElem.id == "supporterKeyPage" + }]; + + }, + + ensureWebSocket: function (systemInfo) { + + if (!("WebSocket" in window)) { + // Not supported by the browser + return; + } + + if (Dashboard.webSocket) { + if (Dashboard.webSocket.readyState === WebSocket.OPEN || Dashboard.webSocket.readyState === WebSocket.CONNECTING) { + return; + } + } + + systemInfo = systemInfo || Dashboard.lastSystemInfo; + + var url = "ws://" + ApiClient.serverHostName + ":" + systemInfo.WebSocketPortNumber + "/mediabrowser"; + + var ws = new WebSocket(url); + + ws.onmessage = Dashboard.onWebSocketMessage; + + ws.onopen = function () { + setTimeout(function () { + $(document).trigger("websocketopen"); + }, 500); + }; + ws.onerror = function () { + setTimeout(function () { + $(document).trigger("websocketerror"); + }, 0); + }; + ws.onclose = function () { + setTimeout(function () { + $(document).trigger("websocketclose"); + }, 0); + }; + + Dashboard.webSocket = ws; + }, + + resetWebSocketPingInterval: function () { + + if (Dashboard.pingWebSocketInterval) { + clearInterval(Dashboard.pingWebSocketInterval); + Dashboard.pingWebSocketInterval = null; + } + Dashboard.pingWebSocketInterval = setInterval(Dashboard.pingWebSocket, 30000); + }, + + pingWebSocket: function () { + + // Send a ping to the server every so often to try and keep the connection alive + if (Dashboard.isWebSocketOpen()) { + Dashboard.sendWebSocketMessage("ping"); + } + + }, + + onWebSocketMessage: function (msg) { + + msg = JSON.parse(msg.data); + + if (msg.MessageType === "LibraryChanged") { + Dashboard.processLibraryUpdateNotification(msg.Data); + } + else if (msg.MessageType === "UserDeleted") { + Dashboard.validateCurrentUser(); + } + else if (msg.MessageType === "SystemInfo") { + Dashboard.updateSystemInfo(msg.Data); + } + else if (msg.MessageType === "HasPendingRestartChanged") { + Dashboard.updateSystemInfo(msg.Data); + } + else if (msg.MessageType === "UserUpdated") { + Dashboard.validateCurrentUser(); + + var user = msg.Data; + + if (user.Id == Dashboard.getCurrentUserId()) { + + $('.currentUsername').html(user.Name); + } + } + else if (msg.MessageType === "PackageInstallationCompleted") { + Dashboard.showPackageInstallNotification(msg.Data, "completed"); + Dashboard.refreshSystemInfoFromServer(); + } + else if (msg.MessageType === "PackageInstallationFailed") { + Dashboard.showPackageInstallNotification(msg.Data, "failed"); + Dashboard.refreshSystemInfoFromServer(); + } + else if (msg.MessageType === "PackageInstallationCancelled") { + Dashboard.showPackageInstallNotification(msg.Data, "cancelled"); + Dashboard.refreshSystemInfoFromServer(); + } + else if (msg.MessageType === "PackageInstalling") { + Dashboard.showPackageInstallNotification(msg.Data, "progress"); + Dashboard.refreshSystemInfoFromServer(); + } + else if (msg.MessageType === "ScheduledTaskEndExecute") { + + Dashboard.showTaskCompletionNotification(msg.Data); + } + + $(document).trigger("websocketmessage", [msg]); + }, + + sendWebSocketMessage: function (name, data) { + + var msg = { MessageType: name }; + + if (data) { + msg.Data = data; + } + + msg = JSON.stringify(msg); + + Dashboard.webSocket.send(msg); + }, + + isWebSocketOpen: function () { + return Dashboard.webSocket && Dashboard.webSocket.readyState === WebSocket.OPEN; + }, + + showTaskCompletionNotification: function (result) { + + var html = ''; + + if (result.Status == "Completed") { + html += '<img src="css/images/notifications/done.png" class="notificationIcon" />'; + return; + } + else if (result.Status == "Cancelled") { + html += '<img src="css/images/notifications/info.png" class="notificationIcon" />'; + return; + } + else { + html += '<img src="css/images/notifications/error.png" class="notificationIcon" />'; + } + + html += '<span>'; + html += result.Name + " " + result.Status; + html += '</span>'; + + var timeout = 0; + + if (result.Status == 'Cancelled') { + timeout = 2000; + } + + Dashboard.showFooterNotification({ html: html, id: result.Id, forceShow: true, timeout: timeout }); + }, + + showPackageInstallNotification: function (installation, status) { + + var html = ''; + + if (status == 'completed') { + html += '<img src="css/images/notifications/done.png" class="notificationIcon" />'; + } + else if (status == 'cancelled') { + html += '<img src="css/images/notifications/info.png" class="notificationIcon" />'; + } + else if (status == 'failed') { + html += '<img src="css/images/notifications/error.png" class="notificationIcon" />'; + } + else if (status == 'progress') { + html += '<img src="css/images/notifications/download.png" class="notificationIcon" />'; + } + + html += '<span style="margin-right: 1em;">'; + + if (status == 'completed') { + html += installation.Name + ' ' + installation.Version + ' installation completed'; + } + else if (status == 'cancelled') { + html += installation.Name + ' ' + installation.Version + ' installation was cancelled'; + } + else if (status == 'failed') { + html += installation.Name + ' ' + installation.Version + ' installation failed'; + } + else if (status == 'progress') { + html += 'Installing ' + installation.Name + ' ' + installation.Version; + } + + html += '</span>'; + + if (status == 'progress') { + + var percentComplete = Math.round(installation.PercentComplete || 0); + + html += '<progress style="margin-right: 1em;" max="100" value="' + percentComplete + '" title="' + percentComplete + '%">'; + html += '' + percentComplete + '%'; + html += '</progress>'; + + if (percentComplete < 100) { + var btnId = "btnCancel" + installation.Id; + html += '<button id="' + btnId + '" type="button" data-icon="delete" onclick="$(\'' + btnId + '\').button(\'disable\');Dashboard.cancelInstallation(\'' + installation.Id + '\');" data-theme="b" data-inline="true" data-mini="true">Cancel</button>'; + } + } + + var timeout = 0; + + if (status == 'cancelled') { + timeout = 2000; + } + + var forceShow = status != "progress"; + var allowHide = status != "progress" && status != 'cancelled'; + + Dashboard.showFooterNotification({ html: html, id: installation.Id, timeout: timeout, forceShow: forceShow, allowHide: allowHide }); + }, + + processLibraryUpdateNotification: function (data) { + + var newItems = data.ItemsAdded.filter(function (a) { + return !a.IsFolder; + }); + + if (!Dashboard.newItems) { + Dashboard.newItems = []; + } + + for (var i = 0, length = newItems.length ; i < length; i++) { + + Dashboard.newItems.push(newItems[i]); + } + + if (Dashboard.newItemTimeout) { + clearTimeout(Dashboard.newItemTimeout); + } + + Dashboard.newItemTimeout = setTimeout(Dashboard.onNewItemTimerStopped, 60000); + }, + + onNewItemTimerStopped: function () { + + var newItems = Dashboard.newItems; + + newItems = newItems.sort(function (a, b) { + + if (a.PrimaryImageTag && b.PrimaryImageTag) { + return 0; + } + + if (a.PrimaryImageTag) { + return -1; + } + + return 1; + }); + + Dashboard.newItems = []; + Dashboard.newItemTimeout = null; + + // Show at most 3 notifications + for (var i = 0, length = Math.min(newItems.length, 3) ; i < length; i++) { + + var item = newItems[i]; + + var data = { + title: "New " + item.Type, + body: item.Name, + timeout: 6000 + }; + + if (item.PrimaryImageTag) { + data.icon = ApiClient.getImageUrl(item.Id, { + width: 100, + tag: item.PrimaryImageTag + }); + } + + WebNotifications.show(data); + } + }, + + ensurePageTitle: function (page) { + + if (!page.hasClass('type-interior')) { + return; + } + + var pageElem = page[0]; + + if (pageElem.hasPageTitle) { + return; + } + + var parent = $('.content-primary', page); + + if (!parent.length) { + parent = $('.ui-content', page)[0]; + } + + $(parent).prepend("<h2 class='pageTitle'>" + (document.title || " ") + "</h2>"); + + pageElem.hasPageTitle = true; + }, + + setPageTitle: function (title) { + + $('.pageTitle', $.mobile.activePage).html(title); + + if (title) { + document.title = title; + } + }, + + metroColors: ["#6FBD45", "#4BB3DD", "#4164A5", "#E12026", "#800080", "#E1B222", "#008040", "#0094FF", "#FF00C7", "#FF870F", "#7F0037"], + + getRandomMetroColor: function () { + + var index = Math.floor(Math.random() * (Dashboard.metroColors.length - 1)); + + return Dashboard.metroColors[index]; + } + +}; + +$(function () { + + var footerHtml = '<div id="footer" class="ui-bar-a">'; + + footerHtml += '<div id="nowPlayingBar" style="display:none;">'; + + footerHtml += '<button id="previousTrackButton" class="imageButton mediaButton" title="Previous Track" type="button"><img src="css/images/media/previousTrack.png" /></button>'; + + footerHtml += '<button id="stopButton" class="imageButton mediaButton" title="Stop" type="button" onclick="MediaPlayer.stop();"><img src="css/images/media/stop.png" /></button>'; + + footerHtml += '<button id="nextTrackButton" class="imageButton mediaButton" title="Next Track" type="button"><img src="css/images/media/nextTrack.png" /></button>'; + + footerHtml += '<div id="mediaElement"></div>'; + + footerHtml += '</div>'; + + footerHtml += '<div id="footerNotifications"></div>'; + + footerHtml += '</div>'; + + + $(document.body).append(footerHtml); +}); + +Dashboard.jQueryMobileInit(); + +$(document).on('pagebeforeshow', ".page", function () { + + Dashboard.refreshSystemInfoFromServer(); + + var page = $(this); + + Dashboard.ensureHeader(page); + Dashboard.ensurePageTitle(page); + +}).on('pageinit', ".page", function () { + + var page = $(this); + var hasLogin = Dashboard.getCurrentUserId(); + + if (!hasLogin) { + + if (this.id !== "loginPage" && !page.hasClass('wizardPage')) { + + Dashboard.logout(); + } + } + + else { + + Dashboard.getCurrentUser().done(function (user) { + + if (user.Configuration.IsAdministrator) { + Dashboard.ensureToolsMenu(page); + } + }); + } +});
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/support.html b/MediaBrowser.WebDashboard/Html/support.html new file mode 100644 index 0000000000..83ebc26485 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/support.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html> +<head> + <title>Support</title> +</head> +<body> + <div id="supportPage" data-role="page" class="page type-interior"> + + <div data-role="content"> + <div class="content-primary"> + <div class="readOnlyContent"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> + <a href="support.html" data-role="button" class="ui-btn-active">General</a> + <a href="log.html" data-role="button">View Log</a> + <a href="supporter.html" data-role="button">Become a Supporter</a> + <a href="supporterKey.html" data-role="button">Supporter Key</a> + </div> + <h2>General Help</h2> + <p> + Media Browser has a thriving community of users and a vast knowledge base of information to help you get the most + out of your media collection. + </p> + <p> + The Community Tracker is a place where you can ask questions, post feature requests and report bugs and get timely + <em>and friendly</em> help from a thriving community of users and developers. + </p> + <a data-role="button" data-icon="arrow-r" data-iconpos="right" href="http://community.mediabrowser.tv" target="_blank">Visit the Community Tracker</a> + <p> + Also, within the tracker, there is a large Knowledge Base of information compiled from users and developers to help you get the + most out of Media Browser. + </p> + <a data-role="button" data-icon="search" data-iconpos="right" href="http://community.mediabrowser.tv/topics?category_id=5&&status=published" target="_blank">Search the Knowledge Base</a> + <p> + Finally, you can visit the Media Browser Web site to see what's happening with MB now and keep up with the developer blog. + </p> + <a data-role="button" data-icon="home" data-iconpos="right" href="http://forum.mediabrowser3.com" target="_blank">Visit the Media Browser Web Site</a> + </div> + </div> + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/supporter.html b/MediaBrowser.WebDashboard/Html/supporter.html new file mode 100644 index 0000000000..a642de8103 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/supporter.html @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<html> +<head> + <title>Support</title> +</head> +<body> + <div id="supporterPage" data-role="page" class="page type-interior"> + + <div data-role="content"> + <div class="content-primary"> + <div class="readOnlyContent"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> + <a href="support.html" data-role="button">General</a> + <a href="log.html" data-role="button">View Log</a> + <a href="supporter.html" data-role="button" class="ui-btn-active">Become a Supporter</a> + <a href="supporterKey.html" data-role="button">Supporter Key</a> + </div> + <h2>Support the Media Browser Team</h2> + <p> + By becoming a Media Browser Supporter, you ensure the continued development and support of this product <strong>and open up a whole new world of premium plug-ins.</strong> + </p> + <p style="margin-bottom: 30px"> + A portion of all MB3 Supporter donations is also contributed to some of our metadata providers (<a href="http://themoviedb.org" target="_blank">The Movie Db</a>, + <a href="http://thetvdb.com" target="_blank">The TVdb</a>, and <a href="http://fanart.tv" target="_blank">FanArt.tv</a>) + </p> + <p style="margin-bottom: 30px"> + Premium plug-ins can be installed and used for their trial periods (14 days on any particular machine) but, to register them for use + beyond that period, you also have to be a Media Browser Supporter. + + </p> + <div style="display: none; padding: 10px 10px 10px 10px; margin-bottom: 10px" class="ui-bar-e supporterOnly"> + <p> + <strong><em>Thank You</em></strong> for your past support of the Media Browser Team. Users like you make it possible for + Media Browser to exist and keep getting better and better. You can always support us again if you feel you are getting maximum + value from the product. + + </p> + </div> + <form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr" + method="post"> + <label for="donateAmt" >Amount (USD)</label> + <select id="donateAmt" name="amount" > + <option>10</option> + <option>15</option> + <option>20</option> + <option>30</option> + <option>50</option> + </select> + + <input type="hidden" name="cmd" value="_xclick"> + <input type="hidden" name="business" value="donate@mediabrowser3.com"> + <input type="hidden" name="currency_code" value="USD"> + <input type="hidden" name="item_name" value="Media Browser Supporter"> + <input type="hidden" name="item_number" value="MBSupporter"> + <input type="hidden" name="notify_url" value="http://mb3admin.com/admin/service/services/ppipn.php"> + <input type="hidden" name="return" id ="paypalReturnUrl" value="#"> + <a data-role="button" onclick="_xclick.submit();"><img src="css/images/donatepp.png"/></a> + + <p><small><em>This button is now <strong>live</strong>. Transactions will result in real money being transferred.</em></small></p> + + + </form> + + </div> + </div> + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/supporterKey.html b/MediaBrowser.WebDashboard/Html/supporterKey.html new file mode 100644 index 0000000000..9d52c6cd69 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/supporterKey.html @@ -0,0 +1,73 @@ +<!DOCTYPE html> +<html> +<head> + <title>Support</title> +</head> +<body> + <div id="supporterKeyPage" data-role="page" class="page type-interior"> + + <div data-role="content"> + <div class="content-primary"> + <div class="readOnlyContent"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> + <a href="support.html" data-role="button">General</a> + <a href="log.html" data-role="button">View Log</a> + <a href="supporter.html" data-role="button">Become a Supporter</a> + <a href="supporterKey.html" data-role="button" class="ui-btn-active">Supporter Key</a> + </div> + <h2>Supporter Key</h2> + </div> + <form id="supporterKeyForm"> + <div style="margin-top: 40px; margin-bottom: 40px"> + <label for="txtSupporterKey">MB3 Supporter Key (paste from email)</label> + <input type="password" id="txtSupporterKey" name="txtSupporterKey" data-inline="true" /> + <div class="fieldDescription"> + <strong>After becoming a supporter, you will be emailed a Supporter Key. Simply copy and paste that key into this field and start + enjoying everything the community has developed for Media Browser. <em>Only MB 3 Supporter Keys are valid here</em></strong> + </div> + + </div> + <div style="margin-top: 40px; margin-bottom: 40px"> + <label for="txtLegacyKey">Legacy Supporter Key (from MB 2.x)</label> + <input type="password" id="txtLegacyKey" name="txtLegacyKey" data-inline="true" /> + <div class="fieldDescription"> + <strong>Some premium plug-ins may give credit for registrations with previous versions in MB 2.x. Enter your MB 2.x + Supporter Key here to allow that credit. + </strong> + </div> + + </div> + <p> + <button type="submit" id="mbLegacyKeyBtn" data-theme="b">Save</button> + + </p> + + </form> + <hr/> + <h2>Lost Key</h2> + <form id="lostKeyForm"> + <div style="margin-top: 40px; margin-bottom: 40px"> + <label for="txtEmail">Email Address</label> + <input type="email" required id="txtEmail" name="txtEmail" data-inline="true" /> + <div class="fieldDescription"> + <strong>If you have lost your key, enter the email address associated with your PayPal account here and hit "Retrieve Key". The key + will be emailed to you and you can come back here and paste it above.</strong> + </div> + + </div> + <p> + <button type="submit" id="mbRetrieveKeyBtn" data-theme="b" >Retrieve Key</button> + + </p> + + </form> + + </div> + </div> + <script type="text/javascript"> + $('#supporterKeyForm').on('submit', SupporterKeyPage.updateSupporterKey); + $('#lostKeyForm').on('submit', SupporterKeyPage.retrieveSupporterKey); + </script> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons-v2.png b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons-v2.png Binary files differnew file mode 100644 index 0000000000..4293bcde95 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons-v2.png diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons.png b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons.png Binary files differnew file mode 100644 index 0000000000..eb03089485 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/faicons.png diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.eot b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.eot Binary files differnew file mode 100644 index 0000000000..11d2f415f4 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.eot diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.woff b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.woff Binary files differnew file mode 100644 index 0000000000..7e892f8782 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/font/fontawesome-webfont.woff diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/ajax-loader.png b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/ajax-loader.png Binary files differnew file mode 100644 index 0000000000..0973ae040f --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/ajax-loader.png diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-black-pack.png b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-black-pack.png Binary files differnew file mode 100644 index 0000000000..07d96586cd --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-black-pack.png diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-white-pack.png b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-white-pack.png Binary files differnew file mode 100644 index 0000000000..0159f628f4 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-18-white-pack.png diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-black-pack.png b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-black-pack.png Binary files differnew file mode 100644 index 0000000000..562e839b9b --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-black-pack.png diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-white-pack.png b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-white-pack.png Binary files differnew file mode 100644 index 0000000000..81f082a4ad --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/images/icons-36-white-pack.png diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/index.html b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/index.html new file mode 100644 index 0000000000..7d3a8cc212 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/index.html @@ -0,0 +1,305 @@ +<!doctype html> +<html> +<head> + <title> jQuery Mobile Icon Pack</title> + + <meta name="viewport" content="width=device-width, initial-scale=1"> + + <!-- jQuery Mobile CSS bits --> + <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" /> + + <!-- Custom css --> + <link rel="stylesheet" href="jqm-icon-pack-3.0.0-fa.css" /> + + <!-- Javascript includes --> + <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script> + <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script> +</head> +<body> + <div data-role="page"> + + <div data-role="header"> + <a href="../index.html" data-icon="home">Back</a> + <h1>jQuery Mobile Icon Pack</h1> + </div> + + <div data-role="content"> + + <a href="http://jqmiconpack.andymatthews.net" data-ajax="false" data-role="button" data-theme="e">Build your own!</a> + <a href="https://github.com/commadelimited/jQuery-Mobile-Icon-Pack" data-role="button">Download the Icon Pack</a> + + <h3>Font Awesome Icons</h3> + <a href="index.html" data-role="button" data-icon="cloud-download" data-theme="b">data-icon="cloud-download"</a> + <a href="index.html" data-role="button" data-icon="cloud-upload" data-theme="b">data-icon="cloud-upload"</a> + <a href="index.html" data-role="button" data-icon="lightbulb" data-theme="b">data-icon="lightbulb"</a> + <a href="index.html" data-role="button" data-icon="exchange" data-theme="b">data-icon="exchange"</a> + <a href="index.html" data-role="button" data-icon="bell-alt" data-theme="b">data-icon="bell-alt"</a> + <a href="index.html" data-role="button" data-icon="file-alt" data-theme="b">data-icon="file-alt"</a> + <a href="index.html" data-role="button" data-icon="beer" data-theme="b">data-icon="beer"</a> + <a href="index.html" data-role="button" data-icon="coffee" data-theme="b">data-icon="coffee"</a> + <a href="index.html" data-role="button" data-icon="food" data-theme="b">data-icon="food"</a> + <a href="index.html" data-role="button" data-icon="fighter-jet" data-theme="b">data-icon="fighter-jet"</a> + <a href="index.html" data-role="button" data-icon="user-md" data-theme="b">data-icon="user-md"</a> + <a href="index.html" data-role="button" data-icon="stethoscope" data-theme="b">data-icon="stethoscope"</a> + <a href="index.html" data-role="button" data-icon="suitcase" data-theme="b">data-icon="suitcase"</a> + <a href="index.html" data-role="button" data-icon="building" data-theme="b">data-icon="building"</a> + <a href="index.html" data-role="button" data-icon="hospital" data-theme="b">data-icon="hospital"</a> + <a href="index.html" data-role="button" data-icon="ambulance" data-theme="b">data-icon="ambulance"</a> + <a href="index.html" data-role="button" data-icon="medkit" data-theme="b">data-icon="medkit"</a> + <a href="index.html" data-role="button" data-icon="h-sign" data-theme="b">data-icon="h-sign"</a> + <a href="index.html" data-role="button" data-icon="plus-sign-alt" data-theme="b">data-icon="plus-sign-alt"</a> + <a href="index.html" data-role="button" data-icon="spinner" data-theme="b">data-icon="spinner"</a> + <a href="index.html" data-role="button" data-icon="angle-left" data-theme="b">data-icon="angle-left"</a> + <a href="index.html" data-role="button" data-icon="angle-right" data-theme="b">data-icon="angle-right"</a> + <a href="index.html" data-role="button" data-icon="angle-up" data-theme="b">data-icon="angle-up"</a> + <a href="index.html" data-role="button" data-icon="angle-down" data-theme="b">data-icon="angle-down"</a> + <a href="index.html" data-role="button" data-icon="double-angle-left" data-theme="b">data-icon="double-angle-left"</a> + <a href="index.html" data-role="button" data-icon="double-angle-right" data-theme="b">data-icon="double-angle-right"</a> + <a href="index.html" data-role="button" data-icon="double-angle-up" data-theme="b">data-icon="double-angle-up"</a> + <a href="index.html" data-role="button" data-icon="double-angle-down" data-theme="b">data-icon="double-angle-down"</a> + <a href="index.html" data-role="button" data-icon="circle-blank" data-theme="b">data-icon="circle-blank"</a> + <a href="index.html" data-role="button" data-icon="circle" data-theme="b">data-icon="circle"</a> + <a href="index.html" data-role="button" data-icon="desktop" data-theme="b">data-icon="desktop"</a> + <a href="index.html" data-role="button" data-icon="laptop" data-theme="b">data-icon="laptop"</a> + <a href="index.html" data-role="button" data-icon="tablet" data-theme="b">data-icon="tablet"</a> + <a href="index.html" data-role="button" data-icon="mobile-phone" data-theme="b">data-icon="mobile-phone"</a> + <a href="index.html" data-role="button" data-icon="quote-left" data-theme="b">data-icon="quote-left"</a> + <a href="index.html" data-role="button" data-icon="quote-right" data-theme="b">data-icon="quote-right"</a> + <a href="index.html" data-role="button" data-icon="github-alt" data-theme="b">data-icon="github-alt"</a> + <a href="index.html" data-role="button" data-icon="folder-close-alt" data-theme="b">data-icon="folder-close-alt"</a> + <a href="index.html" data-role="button" data-icon="folder-open-alt" data-theme="b">data-icon="folder-open-alt"</a> + + + + + + + + + <a href="index.html" data-role="button" data-icon="glass">data-icon="glass"</a> + <a href="index.html" data-role="button" data-icon="music">data-icon="music"</a> + <a href="index.html" data-role="button" data-icon="fasearch">data-icon="fasearch"</a> + <a href="index.html" data-role="button" data-icon="envelope">data-icon="envelope"</a> + <a href="index.html" data-role="button" data-icon="heart">data-icon="heart"</a> + <a href="index.html" data-role="button" data-icon="fastar">data-icon="fastar"</a> + <a href="index.html" data-role="button" data-icon="star-empty">data-icon="star-empty"</a> + <a href="index.html" data-role="button" data-icon="user">data-icon="user"</a> + <a href="index.html" data-role="button" data-icon="film">data-icon="film"</a> + <a href="index.html" data-role="button" data-icon="th-large">data-icon="th-large"</a> + <a href="index.html" data-role="button" data-icon="th">data-icon="th"</a> + <a href="index.html" data-role="button" data-icon="th-list">data-icon="th-list"</a> + <a href="index.html" data-role="button" data-icon="ok">data-icon="ok"</a> + <a href="index.html" data-role="button" data-icon="remove">data-icon="remove"</a> + <a href="index.html" data-role="button" data-icon="zoom-in">data-icon="zoom-in"</a> + <a href="index.html" data-role="button" data-icon="zoom-out">data-icon="zoom-out"</a> + <a href="index.html" data-role="button" data-icon="off">data-icon="off"</a> + <a href="index.html" data-role="button" data-icon="signal">data-icon="signal"</a> + <a href="index.html" data-role="button" data-icon="cog">data-icon="cog"</a> + <a href="index.html" data-role="button" data-icon="trash">data-icon="trash"</a> + <a href="index.html" data-role="button" data-icon="fahome">data-icon="fahome"</a> + <a href="index.html" data-role="button" data-icon="file">data-icon="file"</a> + <a href="index.html" data-role="button" data-icon="time">data-icon="time"</a> + <a href="index.html" data-role="button" data-icon="road">data-icon="road"</a> + <a href="index.html" data-role="button" data-icon="download-alt">data-icon="download-alt"</a> + <a href="index.html" data-role="button" data-icon="download">data-icon="download"</a> + <a href="index.html" data-role="button" data-icon="upload">data-icon="upload"</a> + <a href="index.html" data-role="button" data-icon="inbox">data-icon="inbox"</a> + <a href="index.html" data-role="button" data-icon="play-circle">data-icon="play-circle"</a> + <a href="index.html" data-role="button" data-icon="repeat">data-icon="repeat"</a> + <a href="index.html" data-role="button" data-icon="farefresh">data-icon="farefresh"</a> + <a href="index.html" data-role="button" data-icon="list-alt">data-icon="list-alt"</a> + <a href="index.html" data-role="button" data-icon="lock">data-icon="lock"</a> + <a href="index.html" data-role="button" data-icon="flag">data-icon="flag"</a> + <a href="index.html" data-role="button" data-icon="headphones">data-icon="headphones"</a> + <a href="index.html" data-role="button" data-icon="volume-off">data-icon="volume-off"</a> + <a href="index.html" data-role="button" data-icon="volume-down">data-icon="volume-down"</a> + <a href="index.html" data-role="button" data-icon="volume-up">data-icon="volume-up"</a> + <a href="index.html" data-role="button" data-icon="qrcode">data-icon="qrcode"</a> + <a href="index.html" data-role="button" data-icon="barcode">data-icon="barcode"</a> + <a href="index.html" data-role="button" data-icon="tag">data-icon="tag"</a> + <a href="index.html" data-role="button" data-icon="tags">data-icon="tags"</a> + <a href="index.html" data-role="button" data-icon="book">data-icon="book"</a> + <a href="index.html" data-role="button" data-icon="bookmark">data-icon="bookmark"</a> + <a href="index.html" data-role="button" data-icon="print">data-icon="print"</a> + <a href="index.html" data-role="button" data-icon="camera">data-icon="camera"</a> + <a href="index.html" data-role="button" data-icon="font">data-icon="font"</a> + <a href="index.html" data-role="button" data-icon="bold">data-icon="bold"</a> + <a href="index.html" data-role="button" data-icon="italic">data-icon="italic"</a> + <a href="index.html" data-role="button" data-icon="text-height">data-icon="text-height"</a> + <a href="index.html" data-role="button" data-icon="text-width">data-icon="text-width"</a> + <a href="index.html" data-role="button" data-icon="align-left">data-icon="align-left"</a> + <a href="index.html" data-role="button" data-icon="align-center">data-icon="align-center"</a> + <a href="index.html" data-role="button" data-icon="align-right">data-icon="align-right"</a> + <a href="index.html" data-role="button" data-icon="align-justify">data-icon="align-justify"</a> + <a href="index.html" data-role="button" data-icon="list">data-icon="list"</a> + <a href="index.html" data-role="button" data-icon="indent-left">data-icon="indent-left"</a> + <a href="index.html" data-role="button" data-icon="indent-right">data-icon="indent-right"</a> + <a href="index.html" data-role="button" data-icon="facetime-video">data-icon="facetime-video"</a> + <a href="index.html" data-role="button" data-icon="picture">data-icon="picture"</a> + <a href="index.html" data-role="button" data-icon="pencil">data-icon="pencil"</a> + <a href="index.html" data-role="button" data-icon="map-marker">data-icon="map-marker"</a> + <a href="index.html" data-role="button" data-icon="adjust">data-icon="adjust"</a> + <a href="index.html" data-role="button" data-icon="tint">data-icon="tint"</a> + <a href="index.html" data-role="button" data-icon="edit">data-icon="edit"</a> + <a href="index.html" data-role="button" data-icon="share">data-icon="share"</a> + <a href="index.html" data-role="button" data-icon="facheck">data-icon="facheck"</a> + <a href="index.html" data-role="button" data-icon="move">data-icon="move"</a> + <a href="index.html" data-role="button" data-icon="step-backward">data-icon="step-backward"</a> + <a href="index.html" data-role="button" data-icon="fast-backward">data-icon="fast-backward"</a> + <a href="index.html" data-role="button" data-icon="backward">data-icon="backward"</a> + <a href="index.html" data-role="button" data-icon="play">data-icon="play"</a> + <a href="index.html" data-role="button" data-icon="pause">data-icon="pause"</a> + <a href="index.html" data-role="button" data-icon="stop">data-icon="stop"</a> + <a href="index.html" data-role="button" data-icon="faforward">data-icon="faforward"</a> + <a href="index.html" data-role="button" data-icon="fast-forward">data-icon="fast-forward"</a> + <a href="index.html" data-role="button" data-icon="step-forward">data-icon="step-forward"</a> + <a href="index.html" data-role="button" data-icon="eject">data-icon="eject"</a> + <a href="index.html" data-role="button" data-icon="chevron-left">data-icon="chevron-left"</a> + <a href="index.html" data-role="button" data-icon="chevron-right">data-icon="chevron-right"</a> + <a href="index.html" data-role="button" data-icon="plus-sign">data-icon="plus-sign"</a> + <a href="index.html" data-role="button" data-icon="minus-sign">data-icon="minus-sign"</a> + <a href="index.html" data-role="button" data-icon="remove-sign">data-icon="remove-sign"</a> + <a href="index.html" data-role="button" data-icon="ok-sign">data-icon="ok-sign"</a> + <a href="index.html" data-role="button" data-icon="question-sign">data-icon="question-sign"</a> + <a href="index.html" data-role="button" data-icon="info-sign">data-icon="info-sign"</a> + <a href="index.html" data-role="button" data-icon="screenshot">data-icon="screenshot"</a> + <a href="index.html" data-role="button" data-icon="remove-circle">data-icon="remove-circle"</a> + <a href="index.html" data-role="button" data-icon="ok-circle">data-icon="ok-circle"</a> + <a href="index.html" data-role="button" data-icon="ban-circle">data-icon="ban-circle"</a> + <a href="index.html" data-role="button" data-icon="arrow-left">data-icon="arrow-left"</a> + <a href="index.html" data-role="button" data-icon="arrow-right">data-icon="arrow-right"</a> + <a href="index.html" data-role="button" data-icon="arrow-up">data-icon="arrow-up"</a> + <a href="index.html" data-role="button" data-icon="arrow-down">data-icon="arrow-down"</a> + <a href="index.html" data-role="button" data-icon="share-alt">data-icon="share-alt"</a> + <a href="index.html" data-role="button" data-icon="resize-full">data-icon="resize-full"</a> + <a href="index.html" data-role="button" data-icon="resize-small">data-icon="resize-small"</a> + <a href="index.html" data-role="button" data-icon="faplus">data-icon="faplus"</a> + <a href="index.html" data-role="button" data-icon="faminus">data-icon="faminus"</a> + <a href="index.html" data-role="button" data-icon="asterisk">data-icon="asterisk"</a> + <a href="index.html" data-role="button" data-icon="exclamation-sign">data-icon="exclamation-sign"</a> + <a href="index.html" data-role="button" data-icon="gift">data-icon="gift"</a> + <a href="index.html" data-role="button" data-icon="leaf">data-icon="leaf"</a> + <a href="index.html" data-role="button" data-icon="fire">data-icon="fire"</a> + <a href="index.html" data-role="button" data-icon="eye-open">data-icon="eye-open"</a> + <a href="index.html" data-role="button" data-icon="eye-close">data-icon="eye-close"</a> + <a href="index.html" data-role="button" data-icon="warning-sign">data-icon="warning-sign"</a> + <a href="index.html" data-role="button" data-icon="plane">data-icon="plane"</a> + <a href="index.html" data-role="button" data-icon="calendar">data-icon="calendar"</a> + <a href="index.html" data-role="button" data-icon="random">data-icon="random"</a> + <a href="index.html" data-role="button" data-icon="comment">data-icon="comment"</a> + <a href="index.html" data-role="button" data-icon="magnet">data-icon="magnet"</a> + <a href="index.html" data-role="button" data-icon="chevron-up">data-icon="chevron-up"</a> + <a href="index.html" data-role="button" data-icon="chevron-down">data-icon="chevron-down"</a> + <a href="index.html" data-role="button" data-icon="retweet">data-icon="retweet"</a> + <a href="index.html" data-role="button" data-icon="shopping-cart">data-icon="shopping-cart"</a> + <a href="index.html" data-role="button" data-icon="folder-close">data-icon="folder-close"</a> + <a href="index.html" data-role="button" data-icon="folder-open">data-icon="folder-open"</a> + <a href="index.html" data-role="button" data-icon="resize-vertical">data-icon="resize-vertical"</a> + <a href="index.html" data-role="button" data-icon="resize-horizontal">data-icon="resize-horizontal"</a> + <a href="index.html" data-role="button" data-icon="bar-chart">data-icon="bar-chart"</a> + <a href="index.html" data-role="button" data-icon="twitter-sign">data-icon="twitter-sign"</a> + <a href="index.html" data-role="button" data-icon="facebook-sign">data-icon="facebook-sign"</a> + <a href="index.html" data-role="button" data-icon="camera-retro">data-icon="camera-retro"</a> + <a href="index.html" data-role="button" data-icon="key">data-icon="key"</a> + <a href="index.html" data-role="button" data-icon="cogs">data-icon="cogs"</a> + <a href="index.html" data-role="button" data-icon="comments">data-icon="comments"</a> + <a href="index.html" data-role="button" data-icon="thumbs-up">data-icon="thumbs-up"</a> + <a href="index.html" data-role="button" data-icon="thumbs-down">data-icon="thumbs-down"</a> + <a href="index.html" data-role="button" data-icon="star-half">data-icon="star-half"</a> + <a href="index.html" data-role="button" data-icon="heart-empty">data-icon="heart-empty"</a> + <a href="index.html" data-role="button" data-icon="signout">data-icon="signout"</a> + <a href="index.html" data-role="button" data-icon="linkedin-sign">data-icon="linkedin-sign"</a> + <a href="index.html" data-role="button" data-icon="pushpin">data-icon="pushpin"</a> + <a href="index.html" data-role="button" data-icon="external-link">data-icon="external-link"</a> + <a href="index.html" data-role="button" data-icon="signin">data-icon="signin"</a> + <a href="index.html" data-role="button" data-icon="trophy">data-icon="trophy"</a> + <a href="index.html" data-role="button" data-icon="github-sign">data-icon="github-sign"</a> + <a href="index.html" data-role="button" data-icon="upload-alt">data-icon="upload-alt"</a> + <a href="index.html" data-role="button" data-icon="lemon">data-icon="lemon"</a> + + + + + <a href="index.html" data-role="button" data-icon="beaker">data-icon="beaker"</a> + <a href="index.html" data-role="button" data-icon="bell">data-icon="bell"</a> + <a href="index.html" data-role="button" data-icon="bolt">data-icon="bolt"</a> + <a href="index.html" data-role="button" data-icon="bookmark-empty">data-icon="bookmark-empty"</a> + <a href="index.html" data-role="button" data-icon="briefcase">data-icon="briefcase"</a> + <a href="index.html" data-role="button" data-icon="bullhorn">data-icon="bullhorn"</a> + <a href="index.html" data-role="button" data-icon="caret-down">data-icon="caret-down"</a> + <a href="index.html" data-role="button" data-icon="caret-left">data-icon="caret-left"</a> + <a href="index.html" data-role="button" data-icon="caret-right">data-icon="caret-right"</a> + <a href="index.html" data-role="button" data-icon="caret-up">data-icon="caret-up"</a> + <a href="index.html" data-role="button" data-icon="certificate">data-icon="certificate"</a> + <a href="index.html" data-role="button" data-icon="check-empty">data-icon="check-empty"</a> + <a href="index.html" data-role="button" data-icon="circle-arrow-down">data-icon="circle-arrow-down"</a> + <a href="index.html" data-role="button" data-icon="circle-arrow-left">data-icon="circle-arrow-left"</a> + <a href="index.html" data-role="button" data-icon="circle-arrow-right">data-icon="circle-arrow-right"</a> + <a href="index.html" data-role="button" data-icon="circle-arrow-up">data-icon="circle-arrow-up"</a> + <a href="index.html" data-role="button" data-icon="cloud">data-icon="cloud"</a> + <a href="index.html" data-role="button" data-icon="columns">data-icon="columns"</a> + <a href="index.html" data-role="button" data-icon="comment-alt">data-icon="comment-alt"</a> + <a href="index.html" data-role="button" data-icon="comments-alt">data-icon="comments-alt"</a> + <a href="index.html" data-role="button" data-icon="copy">data-icon="copy"</a> + <a href="index.html" data-role="button" data-icon="credit-card">data-icon="credit-card"</a> + <a href="index.html" data-role="button" data-icon="cut">data-icon="cut"</a> + <a href="index.html" data-role="button" data-icon="dashboard">data-icon="dashboard"</a> + <a href="index.html" data-role="button" data-icon="envelope-alt">data-icon="envelope-alt"</a> + <a href="index.html" data-role="button" data-icon="facebook">data-icon="facebook"</a> + <a href="index.html" data-role="button" data-icon="filter">data-icon="filter"</a> + <a href="index.html" data-role="button" data-icon="fullscreen">data-icon="fullscreen"</a> + <a href="index.html" data-role="button" data-icon="github">data-icon="github"</a> + <a href="index.html" data-role="button" data-icon="globe">data-icon="globe"</a> + <a href="index.html" data-role="button" data-icon="google-plus-sign">data-icon="google-plus-sign"</a> + <a href="index.html" data-role="button" data-icon="google-plus">data-icon="google-plus"</a> + <a href="index.html" data-role="button" data-icon="group">data-icon="group"</a> + <a href="index.html" data-role="button" data-icon="hand-down">data-icon="hand-down"</a> + <a href="index.html" data-role="button" data-icon="hand-left">data-icon="hand-left"</a> + <a href="index.html" data-role="button" data-icon="hand-right">data-icon="hand-right"</a> + <a href="index.html" data-role="button" data-icon="hand-up">data-icon="hand-up"</a> + <a href="index.html" data-role="button" data-icon="hdd">data-icon="hdd"</a> + <a href="index.html" data-role="button" data-icon="legal">data-icon="legal"</a> + <a href="index.html" data-role="button" data-icon="link">data-icon="link"</a> + <a href="index.html" data-role="button" data-icon="linkedin">data-icon="linkedin"</a> + <a href="index.html" data-role="button" data-icon="list-ol">data-icon="list-ol"</a> + <a href="index.html" data-role="button" data-icon="list-ul">data-icon="list-ul"</a> + <a href="index.html" data-role="button" data-icon="magic">data-icon="magic"</a> + <a href="index.html" data-role="button" data-icon="money">data-icon="money"</a> + <a href="index.html" data-role="button" data-icon="paper-clip">data-icon="paper-clip"</a> + <a href="index.html" data-role="button" data-icon="paste">data-icon="paste"</a> + <a href="index.html" data-role="button" data-icon="phone-sign">data-icon="phone-sign"</a> + <a href="index.html" data-role="button" data-icon="phone">data-icon="phone"</a> + <a href="index.html" data-role="button" data-icon="pinterest-sign">data-icon="pinterest-sign"</a> + <a href="index.html" data-role="button" data-icon="pinterest">data-icon="pinterest"</a> + <a href="index.html" data-role="button" data-icon="reorder">data-icon="reorder"</a> + <a href="index.html" data-role="button" data-icon="rss">data-icon="rss"</a> + <a href="index.html" data-role="button" data-icon="save">data-icon="save"</a> + <a href="index.html" data-role="button" data-icon="sign-blank">data-icon="sign-blank"</a> + <a href="index.html" data-role="button" data-icon="sitemap">data-icon="sitemap"</a> + <a href="index.html" data-role="button" data-icon="sort-down">data-icon="sort-down"</a> + <a href="index.html" data-role="button" data-icon="sort-up">data-icon="sort-up"</a> + <a href="index.html" data-role="button" data-icon="sort">data-icon="sort"</a> + <a href="index.html" data-role="button" data-icon="strikethrough">data-icon="strikethrough"</a> + <a href="index.html" data-role="button" data-icon="table">data-icon="table"</a> + <a href="index.html" data-role="button" data-icon="tasks">data-icon="tasks"</a> + <a href="index.html" data-role="button" data-icon="truck">data-icon="truck"</a> + <a href="index.html" data-role="button" data-icon="twitter">data-icon="twitter"</a> + <a href="index.html" data-role="button" data-icon="umbrella">data-icon="umbrella"</a> + <a href="index.html" data-role="button" data-icon="underline">data-icon="underline"</a> + <a href="index.html" data-role="button" data-icon="undo">data-icon="undo"</a> + <a href="index.html" data-role="button" data-icon="unlock">data-icon="unlock"</a> + <a href="index.html" data-role="button" data-icon="user-md">data-icon="user-md"</a> + <a href="index.html" data-role="button" data-icon="wrench">data-icon="wrench"</a> + </div> + + <p align="center"> + Glyphs courtesy of <a href="http://fortawesome.github.com/Font-Awesome/">FontAwesome</a> + </p> + + <div data-role="footer" data-theme="c"> + <p align="center">© 2013 - Andy Matthews</p> + </div> + + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.css b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.css new file mode 100644 index 0000000000..60408b3aae --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.css @@ -0,0 +1 @@ +.ui-icon{width:20px;height:20px;-moz-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;margin-top:-10px !important;line-height:20px}.ui-icon:before{margin-left:3px}.ui-btn-icon-notext .ui-btn-inner .ui-icon{margin:1px 1px 2px 2px !important}.ui-li-link-alt .ui-btn-inner .ui-icon{margin:-10px -10px auto auto !important}.ui-icon-plus,.ui-icon-minus,.ui-icon-delete,.ui-icon-arrow-r,.ui-icon-arrow-l,.ui-icon-arrow-u,.ui-icon-arrow-d,.ui-icon-check,.ui-icon-gear,.ui-icon-refresh,.ui-icon-forward,.ui-icon-back,.ui-icon-grid,.ui-icon-star,.ui-icon-alert,.ui-icon-info,.ui-icon-home,.ui-icon-search,.ui-icon-searchfield:after,.ui-icon-checkbox-off,.ui-icon-checkbox-on,.ui-icon-radio-off,.ui-icon-radio-on,.ui-icon-email,.ui-icon-page,.ui-icon-question,.ui-icon-foursquare,.ui-icon-dollar,.ui-icon-euro,.ui-icon-pound,.ui-icon-apple,.ui-icon-chat,.ui-icon-trash,.ui-icon-mappin,.ui-icon-direction,.ui-icon-heart,.ui-icon-wrench,.ui-icon-play,.ui-icon-pause,.ui-icon-stop,.ui-icon-person,.ui-icon-music,.ui-icon-wifi,.ui-icon-phone,.ui-icon-power,.ui-icon-lightning,.ui-icon-drink,.ui-icon-android{background-image:url("images/icons-18-white-pack.png") !important}@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min--moz-device-pixel-ratio: 1.5), only screen and (min-resolution: 240dpi){.ui-icon-plus,.ui-icon-minus,.ui-icon-delete,.ui-icon-arrow-r,.ui-icon-arrow-l,.ui-icon-arrow-u,.ui-icon-arrow-d,.ui-icon-check,.ui-icon-gear,.ui-icon-refresh,.ui-icon-forward,.ui-icon-back,.ui-icon-grid,.ui-icon-star,.ui-icon-alert,.ui-icon-info,.ui-icon-home,.ui-icon-search,.ui-icon-searchfield:after,.ui-icon-checkbox-off,.ui-icon-checkbox-on,.ui-icon-radio-off,.ui-icon-radio-on,.ui-icon-email,.ui-icon-page,.ui-icon-question,.ui-icon-foursquare,.ui-icon-dollar,.ui-icon-euro,.ui-icon-pound,.ui-icon-apple,.ui-icon-chat,.ui-icon-trash,.ui-icon-mappin,.ui-icon-direction,.ui-icon-heart,.ui-icon-wrench,.ui-icon-play,.ui-icon-pause,.ui-icon-stop,.ui-icon-person,.ui-icon-music,.ui-icon-wifi,.ui-icon-phone,.ui-icon-power,.ui-icon-lightning,.ui-icon-drink,.ui-icon-android{background-image:url("images/icons-36-white-pack.png");-moz-background-size:774px 54px;-o-background-size:774px 54px;-webkit-background-size:774px 54px;background-size:774px 54px}.ui-icon-alt{background-image:url("images/icons-36-black-pack.png")}}.ui-icon-plus{background-position:0px 1px !important}.ui-icon-minus{background-position:-36px 1px !important}.ui-icon-delete{background-position:-71px 1px !important}.ui-icon-arrow-r{background-position:-107px 1px !important}.ui-icon-arrow-l{background-position:-143px 1px !important}.ui-icon-arrow-u{background-position:-179px 1px !important}.ui-icon-arrow-d{background-position:-215px 1px !important}.ui-icon-check{background-position:-251px 1px !important}.ui-icon-gear{background-position:-287px 1px !important}.ui-icon-refresh{background-position:-323px 1px !important}.ui-icon-forward{background-position:-359px 1px !important}.ui-icon-back{background-position:-396px 0 !important}.ui-icon-grid{background-position:-431px 1px !important}.ui-icon-star{background-position:-467px 1px !important}.ui-icon-alert{background-position:-503px 1px !important}.ui-icon-info{background-position:-539px 1px !important}.ui-icon-home{background-position:-575px 1px !important}.ui-icon-search,.ui-icon-searchfield:after{background-position:-611px 0px !important}.ui-icon-checkbox-off{background-position:-681px 1px !important}.ui-icon-checkbox-on{background-position:-647px 1px !important}.ui-icon-radio-off{background-position:-752px 1px !important}.ui-icon-radio-on{background-position:-717px 1px !important}.ui-icon-email{background-position:1px -17px !important}.ui-icon-page{background-position:-36px -17px !important}.ui-icon-question{background-position:-71px -17px !important}.ui-icon-foursquare{background-position:-107px -17px !important}.ui-icon-dollar{background-position:-215px -17px !important}.ui-icon-euro{background-position:-251px -17px !important}.ui-icon-pound{background-position:-287px -17px !important}.ui-icon-apple{background-position:-323px -17px !important}.ui-icon-chat{background-position:-359px -17px !important}.ui-icon-trash{background-position:-395px -17px !important}.ui-icon-mappin{background-position:-467px -17px !important}.ui-icon-direction{background-position:-503px -17px !important}.ui-icon-heart{background-position:-539px -17px !important}.ui-icon-wrench{background-position:-575px -17px !important}.ui-icon-play{background-position:-611px -17px !important}.ui-icon-pause{background-position:-647px -17px !important}.ui-icon-stop{background-position:-683px -17px !important}.ui-icon-person{background-position:-719px -17px !important}.ui-icon-music{background-position:-755px -17px !important}.ui-icon-wifi{background-position:-35px -34px !important}.ui-icon-phone{background-position:-72px -36px !important}.ui-icon-power{background-position:-107px -35px !important}.ui-icon-lightning{background-position:-251px -35px !important}.ui-icon-android{background-position:-323px -35px !important}@font-face{font-family:'FontAwesome';src:url("font/fontawesome-webfont.eot");src:url("font/fontawesome-webfont.eot?#iefix") format("embedded-opentype"),url("font/fontawesome-webfont.woff") format("woff"),url("font/fontawesome-webfont.ttf") format("truetype");font-weight:normal;font-style:normal}[class^="ui-icon-"]:before,[class*=" ui-icon-"]:before{font-family:FontAwesome !important;font-weight:normal;font-style:normal;display:inline-block}.ui-icon:not(.ui-icon-loading),.ui-icon-searchfield::after{background:#666666;background:rgba(0,0,0,0.4);color:#ffffff;font-weight:normal;text-shadow:none}.ui-icon-cloud-download:before{content:"\f0ed";margin-left:2px}.ui-icon-cloud-upload:before{content:"\f0ee";margin-left:2px}.ui-icon-lightbulb:before{content:"\f0eb";margin-top:1px;margin-left:3px}.ui-icon-exchange:before{content:"\f0ec"}.ui-icon-bell-alt:before{content:"\f0f3"}.ui-icon-file-alt:before{content:"\f0f6"}.ui-icon-beer:before{content:"\f0fc";margin-top:1px;margin-left:2px}.ui-icon-coffee:before{content:"\f0f4";margin-left:2px}.ui-icon-food:before{content:"\f0f5";margin-top:1px;margin-left:4px}.ui-icon-fighter-jet:before{content:"\f0fb";margin-top:1px;margin-left:2px}.ui-icon-user-md:before{content:"\f0f0"}.ui-icon-stethoscope:before{content:"\f0f1";margin-top:1px;margin-left:4px}.ui-icon-suitcase:before{content:"\f0f2";margin-left:2px}.ui-icon-building:before{content:"\f0f7"}.ui-icon-hospital:before{content:"\f0f8";margin-left:4px}.ui-icon-ambulance:before{content:"\f0f9";margin-top:1px;margin-left:1px}.ui-icon-medkit:before{content:"\f0fa";margin-top:0px;margin-left:2px}.ui-icon-h-sign:before{content:"\f0fd"}.ui-icon-plus-sign-alt:before{content:"\f0fe"}.ui-icon-spinner:before{content:"\f110"}.ui-icon-angle-left:before{content:"\f104"}.ui-icon-angle-right:before{content:"\f105"}.ui-icon-angle-up:before{content:"\f106"}.ui-icon-angle-down:before{content:"\f107"}.ui-icon-double-angle-left:before{content:"\f100"}.ui-icon-double-angle-right:before{content:"\f101";margin-left:4px}.ui-icon-double-angle-up:before{content:"\f102"}.ui-icon-double-angle-down:before{content:"\f103";margin-top:1px}.ui-icon-circle-blank:before{content:"\f10c"}.ui-icon-circle:before{content:"\f111"}.ui-icon-desktop:before{content:"\f108";margin-top:1px;margin-left:2px}.ui-icon-laptop:before{content:"\f109";margin-top:1px;margin-left:2px}.ui-icon-tablet:before{content:"\f10a";margin-top:1px}.ui-icon-mobile-phone:before{content:"\f10b"}.ui-icon-quote-left:before{content:"\f10d"}.ui-icon-quote-right:before{content:"\f10e"}.ui-icon-github-alt:before{content:"\f113"}.ui-icon-folder-close-alt:before{content:"\f114"}.ui-icon-folder-open-alt:before{content:"\f115"}.ui-icon-glass:before{content:"\f000";margin-top:2px}.ui-icon-music:before{content:"\f001";margin-left:1px;margin-top:2px}.ui-icon-fasearch:before{content:"\f002"}.ui-icon-envelope:before{content:"\f003";margin-left:-1px;margin-left:2px;margin-top:1px}.ui-icon-heart:before{content:"\f004";margin-left:3px;margin-top:2px}.ui-icon-fastar:before{content:"\f005"}.ui-icon-star-empty:before{content:"\f006"}.ui-icon-user:before{content:"\f007";margin-left:4px}.ui-icon-film:before{content:"\f008";margin-left:2px}.ui-icon-th-large:before{content:"\f009";margin-left:2px;margin-top:2px}.ui-icon-th:before{content:"\f00a";margin-left:3px;margin-top:2px}.ui-icon-th-list:before{content:"\f00b";margin-left:3px;margin-top:2px}.ui-icon-ok:before{content:"\f00c";margin-left:2px}.ui-icon-remove:before{content:"\f00d";margin-left:3px;margin-top:2px}.ui-icon-zoom-in:before{content:"\f00e"}.ui-icon-zoom-out:before{content:"\f010"}.ui-icon-off:before{content:"\f011"}.ui-icon-signal:before{content:"\f012";margin-left:-1px}.ui-icon-cog:before{content:"\f013";margin-left:3px;margin-top:2px}.ui-icon-trash:before{content:"\f014"}.ui-icon-fahome:before{content:"\f015"}.ui-icon-file:before{content:"\f016"}.ui-icon-time:before{content:"\f017";margin-top:2px}.ui-icon-road:before{content:"\f018"}.ui-icon-download-alt:before{content:"\f019"}.ui-icon-download:before{content:"\f01a";margin-top:2px}.ui-icon-upload:before{content:"\f01b";margin-top:2px}.ui-icon-inbox:before{content:"\f01c"}.ui-icon-play-circle:before{content:"\f01d";margin-top:2px}.ui-icon-repeat:before{content:"\f01e";margin-top:2px}.ui-icon-farefresh:before{content:"\f021";margin-top:2px}.ui-icon-list-alt:before{content:"\f022";margin-left:3px;margin-top:2px}.ui-icon-lock:before{content:"\f023"}.ui-icon-flag:before{content:"\f024";margin-top:2px}.ui-icon-headphones:before{content:"\f025"}.ui-icon-volume-off:before{content:"\f026"}.ui-icon-volume-down:before{content:"\f027"}.ui-icon-volume-up:before{content:"\f028"}.ui-icon-qrcode:before{content:"\f029"}.ui-icon-barcode:before{content:"\f02a"}.ui-icon-tag:before{content:"\f02b"}.ui-icon-tags:before{content:"\f02c"}.ui-icon-book:before{content:"\f02d"}.ui-icon-bookmark:before{content:"\f02e"}.ui-icon-print:before{content:"\f02f"}.ui-icon-camera:before{content:"\f030"}.ui-icon-font:before{content:"\f031";margin-left:2px}.ui-icon-bold:before{content:"\f032";margin-left:2px}.ui-icon-italic:before{content:"\f033"}.ui-icon-text-height:before{content:"\f034"}.ui-icon-text-width:before{content:"\f035"}.ui-icon-align-left:before{content:"\f036"}.ui-icon-align-center:before{content:"\f037"}.ui-icon-align-right:before{content:"\f038"}.ui-icon-align-justify:before{content:"\f039"}.ui-icon-list:before{content:"\f03a"}.ui-icon-indent-left:before{content:"\f03b";margin-left:0px;margin-top:2px}.ui-icon-indent-right:before{content:"\f03c"}.ui-icon-facetime-video:before{content:"\f03d"}.ui-icon-picture:before{content:"\f03e"}.ui-icon-pencil:before{content:"\f040"}.ui-icon-map-marker:before{content:"\f041";margin-left:3px;margin-top:2px}.ui-icon-adjust:before{content:"\f042";margin-top:2px}.ui-icon-tint:before{content:"\f043"}.ui-icon-edit:before{content:"\f044"}.ui-icon-share:before{content:"\f045"}.ui-icon-facheck:before{content:"\f046"}.ui-icon-move:before{content:"\f047"}.ui-icon-step-backward:before{content:"\f048"}.ui-icon-fast-backward:before{content:"\f049"}.ui-icon-backward:before{content:"\f04a"}.ui-icon-play:before{content:"\f04b";margin-left:6px;margin-top:2px}.ui-icon-pause:before{content:"\f04c";margin-top:2px}.ui-icon-stop:before{content:"\f04d";margin-top:2px}.ui-icon-faforward:before{content:"\f04e"}.ui-icon-fast-forward:before{content:"\f050"}.ui-icon-step-forward:before{content:"\f051"}.ui-icon-eject:before{content:"\f052"}.ui-icon-chevron-left:before{content:"\f053";margin-top:2px}.ui-icon-chevron-right:before{content:"\f054";margin-top:2px}.ui-icon-plus-sign:before{content:"\f055";margin-top:2px}.ui-icon-minus-sign:before{content:"\f056";margin-top:2px}.ui-icon-remove-sign:before{content:"\f057";margin-top:2px}.ui-icon-ok-sign:before{content:"\f058";margin-top:2px}.ui-icon-question-sign:before{content:"\f059";margin-top:2px}.ui-icon-info-sign:before{content:"\f05a";margin-top:2px}.ui-icon-screenshot:before{content:"\f05b"}.ui-icon-remove-circle:before{content:"\f05c";margin-top:2px}.ui-icon-ok-circle:before{content:"\f05d";margin-top:2px}.ui-icon-ban-circle:before{content:"\f05e";margin-top:2px}.ui-icon-arrow-left:before{content:"\f060"}.ui-icon-arrow-right:before{content:"\f061"}.ui-icon-arrow-up:before{content:"\f062"}.ui-icon-arrow-down:before{content:"\f063"}.ui-icon-share-alt:before{content:"\f064"}.ui-icon-resize-full:before{content:"\f065"}.ui-icon-resize-small:before{content:"\f066"}.ui-icon-faplus:before{content:"\f067"}.ui-icon-faminus:before{content:"\f068"}.ui-icon-asterisk:before{content:"\f069";margin-top:2px}.ui-icon-exclamation-sign:before{content:"\f06a";margin-top:2px}.ui-icon-gift:before{content:"\f06b"}.ui-icon-leaf:before{content:"\f06c"}.ui-icon-fire:before{content:"\f06d"}.ui-icon-eye-open:before{content:"\f06e"}.ui-icon-eye-close:before{content:"\f070"}.ui-icon-warning-sign:before{content:"\f071"}.ui-icon-plane:before{content:"\f072"}.ui-icon-calendar:before{content:"\f073"}.ui-icon-random:before{content:"\f074"}.ui-icon-comment:before{content:"\f075";margin-top:2px}.ui-icon-magnet:before{content:"\f076";margin-top:2px}.ui-icon-chevron-up:before{content:"\f077"}.ui-icon-chevron-down:before{content:"\f078"}.ui-icon-retweet:before{content:"\f079"}.ui-icon-shopping-cart:before{content:"\f07a"}.ui-icon-folder-close:before{content:"\f07b"}.ui-icon-folder-open:before{content:"\f07c"}.ui-icon-resize-vertical:before{content:"\f07d"}.ui-icon-resize-horizontal:before{content:"\f07e"}.ui-icon-bar-chart:before{content:"\f080"}.ui-icon-twitter-sign:before{content:"\f081"}.ui-icon-facebook-sign:before{content:"\f082"}.ui-icon-camera-retro:before{content:"\f083"}.ui-icon-key:before{content:"\f084"}.ui-icon-cogs:before{content:"\f085"}.ui-icon-comments:before{content:"\f086"}.ui-icon-thumbs-up:before{content:"\f087"}.ui-icon-thumbs-down:before{content:"\f088"}.ui-icon-star-half:before{content:"\f089"}.ui-icon-heart-empty:before{content:"\f08a";margin-top:2px}.ui-icon-signout:before{content:"\f08b"}.ui-icon-linkedin-sign:before{content:"\f08c"}.ui-icon-pushpin:before{content:"\f08d"}.ui-icon-external-link:before{content:"\f08e"}.ui-icon-signin:before{content:"\f090"}.ui-icon-trophy:before{content:"\f091"}.ui-icon-github-sign:before{content:"\f092"}.ui-icon-upload-alt:before{content:"\f093"}.ui-icon-lemon:before{content:"\f094"}.ui-icon-phone:before{content:"\f095"}.ui-icon-check-empty:before{content:"\f096"}.ui-icon-bookmark-empty:before{content:"\f097"}.ui-icon-phone-sign:before{content:"\f098"}.ui-icon-twitter:before{content:"\f099"}.ui-icon-facebook:before{content:"\f09a"}.ui-icon-github:before{content:"\f09b";margin-top:2px}.ui-icon-unlock:before{content:"\f09c"}.ui-icon-credit-card:before{content:"\f09d"}.ui-icon-rss:before{content:"\f09e"}.ui-icon-hdd:before{content:"\f0a0"}.ui-icon-bullhorn:before{content:"\f0a1"}.ui-icon-bell:before{content:"\f0a2"}.ui-icon-certificate:before{content:"\f0a3";margin-top:2px}.ui-icon-hand-right:before{content:"\f0a4"}.ui-icon-hand-left:before{content:"\f0a5"}.ui-icon-hand-up:before{content:"\f0a6"}.ui-icon-hand-down:before{content:"\f0a7"}.ui-icon-circle-arrow-left:before{content:"\f0a8";margin-top:2px}.ui-icon-circle-arrow-right:before{content:"\f0a9";margin-top:2px}.ui-icon-circle-arrow-up:before{content:"\f0aa";margin-top:2px}.ui-icon-circle-arrow-down:before{content:"\f0ab";margin-top:2px}.ui-icon-globe:before{content:"\f0ac";margin-top:2px}.ui-icon-wrench:before{content:"\f0ad"}.ui-icon-tasks:before{content:"\f0ae"}.ui-icon-filter:before{content:"\f0b0"}.ui-icon-briefcase:before{content:"\f0b1"}.ui-icon-fullscreen:before{content:"\f0b2"}.ui-icon-group:before{content:"\f0c0"}.ui-icon-link:before{content:"\f0c1"}.ui-icon-cloud:before{content:"\f0c2"}.ui-icon-beaker:before{content:"\f0c3"}.ui-icon-cut:before{content:"\f0c4"}.ui-icon-copy:before{content:"\f0c5"}.ui-icon-paper-clip:before{content:"\f0c6"}.ui-icon-save:before{content:"\f0c7"}.ui-icon-sign-blank:before{content:"\f0c8"}.ui-icon-reorder:before{content:"\f0c9"}.ui-icon-list-ul:before{content:"\f0ca"}.ui-icon-list-ol:before{content:"\f0cb"}.ui-icon-strikethrough:before{content:"\f0cc"}.ui-icon-underline:before{content:"\f0cd"}.ui-icon-table:before{content:"\f0ce"}.ui-icon-magic:before{content:"\f0d0"}.ui-icon-truck:before{content:"\f0d1"}.ui-icon-pinterest:before{content:"\f0d2";margin-top:2px}.ui-icon-pinterest-sign:before{content:"\f0d3";margin-top:2px}.ui-icon-google-plus-sign:before{content:"\f0d4"}.ui-icon-google-plus:before{content:"\f0d5"}.ui-icon-money:before{content:"\f0d6"}.ui-icon-caret-down:before{content:"\f0d7";margin-top:2px}.ui-icon-caret-up:before{content:"\f0d8"}.ui-icon-caret-left:before{content:"\f0d9";margin-top:2px}.ui-icon-caret-right:before{content:"\f0da";margin-top:2px}.ui-icon-columns:before{content:"\f0db"}.ui-icon-sort:before{content:"\f0dc";margin-top:2px}.ui-icon-sort-down:before{content:"\f0dd"}.ui-icon-sort-up:before{content:"\f0de"}.ui-icon-envelope-alt:before{content:"\f0e0"}.ui-icon-linkedin:before{content:"\f0e1"}.ui-icon-undo:before{content:"\f0e2";margin-top:2px}.ui-icon-legal:before{content:"\f0e3"}.ui-icon-dashboard:before{content:"\f0e4"}.ui-icon-comment-alt:before{content:"\f0e5"}.ui-icon-comments-alt:before{content:"\f0e6"}.ui-icon-bolt:before{content:"\f0e7"}.ui-icon-sitemap:before{content:"\f0e8"}.ui-icon-umbrella:before{content:"\f0e9"}.ui-icon-paste:before{content:"\f0ea"}.ui-icon-user-md:before{content:"\f200"} diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.scss b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.scss new file mode 100644 index 0000000000..2796ac004f --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/font-awesome/jqm-icon-pack-3.0.0-fa.scss @@ -0,0 +1,419 @@ +/* + The following declaration increase the size of the "dot" which contains the icon + This is because some of the font awesome icons are larger than jQuery Mobile icons + It applies to ALL occurrences, but can be commented out or removed if necessary +*/ +.ui-icon { + width: 20px; + height: 20px; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + border-radius: 10px; + margin-top: -10px !important; + line-height: 20px; +} +.ui-icon:before { margin-left: 3px; } + +/* fix for Github issue #6 */ +.ui-btn-icon-notext .ui-btn-inner .ui-icon { + margin: 1px 1px 2px 2px !important; +} +.ui-li-link-alt .ui-btn-inner .ui-icon { + margin: -10px -10px auto auto !important; +} + +/* supporting original icons */ +.ui-icon-plus, .ui-icon-minus, .ui-icon-delete, .ui-icon-arrow-r, +.ui-icon-arrow-l, .ui-icon-arrow-u, .ui-icon-arrow-d, .ui-icon-check, +.ui-icon-gear, .ui-icon-refresh, .ui-icon-forward, .ui-icon-back, +.ui-icon-grid, .ui-icon-star, .ui-icon-alert, .ui-icon-info, .ui-icon-home, .ui-icon-search, .ui-icon-searchfield:after, +.ui-icon-checkbox-off, .ui-icon-checkbox-on, .ui-icon-radio-off, .ui-icon-radio-on, .ui-icon-email , .ui-icon-page, +.ui-icon-question , .ui-icon-foursquare, .ui-icon-dollar , .ui-icon-euro, +.ui-icon-pound , .ui-icon-apple , .ui-icon-chat , .ui-icon-trash , .ui-icon-mappin , .ui-icon-direction, +.ui-icon-heart , .ui-icon-wrench , .ui-icon-play , .ui-icon-pause , .ui-icon-stop , .ui-icon-person , .ui-icon-music, +.ui-icon-wifi , .ui-icon-phone , .ui-icon-power , +.ui-icon-lightning , .ui-icon-drink , .ui-icon-android { + background-image: url('images/icons-18-white-pack.png') !important; +} + +@media only screen and (-webkit-min-device-pixel-ratio: 1.3), + only screen and (-o-min-device-pixel-ratio: 3/2), + only screen and (min--moz-device-pixel-ratio: 1.3), + only screen and (min-device-pixel-ratio: 1.3), + only screen and (min-resolution: 1.3dppx) { + + .ui-icon-plus, .ui-icon-minus, .ui-icon-delete, .ui-icon-arrow-r, + .ui-icon-arrow-l, .ui-icon-arrow-u, .ui-icon-arrow-d, .ui-icon-check, + .ui-icon-gear, .ui-icon-refresh, .ui-icon-forward, .ui-icon-back, + .ui-icon-grid, .ui-icon-star, .ui-icon-alert, .ui-icon-info, .ui-icon-home, .ui-icon-search, .ui-icon-searchfield:after, + .ui-icon-checkbox-off, .ui-icon-checkbox-on, .ui-icon-radio-off, .ui-icon-radio-on, .ui-icon-email , .ui-icon-page, + .ui-icon-question , .ui-icon-foursquare, .ui-icon-dollar , .ui-icon-euro, + .ui-icon-pound , .ui-icon-apple , .ui-icon-chat , .ui-icon-trash , .ui-icon-mappin , .ui-icon-direction, + .ui-icon-heart , .ui-icon-wrench , .ui-icon-play , .ui-icon-pause , .ui-icon-stop , .ui-icon-person , .ui-icon-music, + .ui-icon-wifi , .ui-icon-phone , .ui-icon-power , + .ui-icon-lightning , .ui-icon-drink , .ui-icon-android { + background-image: url('images/icons-36-white-pack.png') !important; + -moz-background-size: 774px 54px; + -o-background-size: 774px 54px; + -webkit-background-size: 774px 54px; + background-size: 774px 54px; + } + .ui-icon-alt { + background-image: url('images/icons-36-black-pack.png'); + } +} + +/* first row */ +.ui-icon-plus { background-position: 0px 1px !important; } +.ui-icon-minus { background-position: -36px 1px !important; } +.ui-icon-delete { background-position: -71px 1px !important; } +.ui-icon-arrow-r { background-position: -107px 1px !important; } +.ui-icon-arrow-l { background-position: -143px 1px !important; } +.ui-icon-arrow-u { background-position: -179px 1px !important; } +.ui-icon-arrow-d { background-position: -215px 1px !important; } +.ui-icon-check { background-position: -251px 1px !important; } +.ui-icon-gear { background-position: -287px 1px !important; } +.ui-icon-refresh { background-position: -323px 1px !important; } +.ui-icon-forward { background-position: -359px 1px !important; } +.ui-icon-back { background-position: -396px -0 !important; } +.ui-icon-grid { background-position: -431px 1px !important; } +.ui-icon-star { background-position: -467px 1px !important; } +.ui-icon-alert { background-position: -503px 1px !important; } +.ui-icon-info { background-position: -539px 1px !important; } +.ui-icon-home { background-position: -575px 1px !important; } +.ui-icon-search,.ui-icon-searchfield:after { background-position: -611px 0px !important; } +.ui-icon-checkbox-off { background-position: -681px 1px !important; } +.ui-icon-checkbox-on { background-position: -647px 1px !important; } +.ui-icon-radio-off { background-position: -752px 1px !important; } +.ui-icon-radio-on { background-position: -717px 1px !important; } + +/* begin icon pack definitions */ +/* second row */ +.ui-icon-email { background-position: 1px -17px !important; } +.ui-icon-page { background-position: -36px -17px !important; } +.ui-icon-question { background-position: -71px -17px !important; } +.ui-icon-foursquare { background-position: -107px -17px !important; } +.ui-icon-dollar { background-position: -215px -17px !important; } +.ui-icon-euro { background-position: -251px -17px !important; } +.ui-icon-pound { background-position: -287px -17px !important; } +.ui-icon-apple { background-position: -323px -17px !important; } +.ui-icon-chat { background-position: -359px -17px !important; } +.ui-icon-trash { background-position: -395px -17px !important; } +.ui-icon-mappin { background-position: -467px -17px !important; } +.ui-icon-direction { background-position: -503px -17px !important; } +.ui-icon-heart { background-position: -539px -17px !important; } +.ui-icon-wrench { background-position: -575px -17px !important; } +.ui-icon-play { background-position: -611px -17px !important; } +.ui-icon-pause { background-position: -647px -17px !important; } +.ui-icon-stop { background-position: -683px -17px !important; } +.ui-icon-person { background-position: -719px -17px !important; } +.ui-icon-music { background-position: -755px -17px !important; } + +/* third row */ +.ui-icon-wifi { background-position: -35px -34px !important; } +.ui-icon-phone { background-position: -72px -36px !important; } +.ui-icon-power { background-position: -107px -35px !important; } +.ui-icon-lightning { background-position: -251px -35px !important; } +.ui-icon-android { background-position: -323px -35px !important; } + + + + +/* begin primary declarations */ +@font-face { + font-family: 'FontAwesome'; + src: url('font/fontawesome-webfont.eot'); + src: url('font/fontawesome-webfont.eot?#iefix') format('embedded-opentype'), + url('font/fontawesome-webfont.woff') format('woff'), + url('font/fontawesome-webfont.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} +[class^="ui-icon-"]:before, [class*=" ui-icon-"]:before { + font-family: FontAwesome !important; + font-weight: normal; + font-style: normal; + display: inline-block; +} +.ui-icon:not(.ui-icon-loading), .ui-icon-searchfield::after { + background: #666666; + background: rgba(0, 0, 0, .4); + color: #ffffff; + font-weight: normal; + text-shadow: none; +} +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen + readers do not read off random characters that represent icons */ +.ui-icon-cloud-download:before { content: "\f0ed"; margin-left: 2px; } +.ui-icon-cloud-upload:before { content: "\f0ee"; margin-left: 2px; } +.ui-icon-lightbulb:before { content: "\f0eb"; margin-top: 1px; margin-left: 3px; } +.ui-icon-exchange:before { content: "\f0ec"; } +.ui-icon-bell-alt:before { content: "\f0f3"; } +.ui-icon-file-alt:before { content: "\f0f6"; } +.ui-icon-beer:before { content: "\f0fc"; margin-top: 1px; margin-left: 2px; } +.ui-icon-coffee:before { content: "\f0f4"; margin-left: 2px; } +.ui-icon-food:before { content: "\f0f5"; margin-top: 1px; margin-left: 4px; } +.ui-icon-fighter-jet:before { content: "\f0fb"; margin-top: 1px; margin-left: 2px; } +.ui-icon-user-md:before { content: "\f0f0"; } +.ui-icon-stethoscope:before { content: "\f0f1"; margin-top: 1px; margin-left: 4px; } +.ui-icon-suitcase:before { content: "\f0f2";; margin-left: 2px; } +.ui-icon-building:before { content: "\f0f7"; } +.ui-icon-hospital:before { content: "\f0f8"; margin-left: 4px; } +.ui-icon-ambulance:before { content: "\f0f9"; margin-top: 1px; margin-left: 1px; } +.ui-icon-medkit:before { content: "\f0fa"; margin-top: 0px; margin-left: 2px; } +.ui-icon-h-sign:before { content: "\f0fd"; } +.ui-icon-plus-sign-alt:before { content: "\f0fe"; } +.ui-icon-spinner:before { content: "\f110"; } +.ui-icon-angle-left:before { content: "\f104"; } +.ui-icon-angle-right:before { content: "\f105"; } +.ui-icon-angle-up:before { content: "\f106"; } +.ui-icon-angle-down:before { content: "\f107"; } +.ui-icon-double-angle-left:before { content: "\f100"; } +.ui-icon-double-angle-right:before { content: "\f101"; margin-left: 4px; } +.ui-icon-double-angle-up:before { content: "\f102"; } +.ui-icon-double-angle-down:before { content: "\f103"; margin-top: 1px; } +.ui-icon-circle-blank:before { content: "\f10c"; } +.ui-icon-circle:before { content: "\f111"; } +.ui-icon-desktop:before { content: "\f108"; margin-top: 1px; margin-left: 2px; } +.ui-icon-laptop:before { content: "\f109"; margin-top: 1px; margin-left: 2px; } +.ui-icon-tablet:before { content: "\f10a"; margin-top: 1px; } +.ui-icon-mobile-phone:before { content: "\f10b"; } +.ui-icon-quote-left:before { content: "\f10d"; } +.ui-icon-quote-right:before { content: "\f10e"; } +.ui-icon-github-alt:before { content: "\f113"; } +.ui-icon-folder-close-alt:before { content: "\f114"; } +.ui-icon-folder-open-alt:before { content: "\f115"; } + +.ui-icon-glass:before { content: "\f000"; margin-top: 2px; } +.ui-icon-music:before { content: "\f001"; margin-left: 1px; margin-top: 2px; } +.ui-icon-fasearch:before { content: "\f002"; } +.ui-icon-envelope:before { content: "\f003"; + margin-left: -1px; + margin-left: 2px; + margin-top: 1px; + } +.ui-icon-heart:before { content: "\f004"; + margin-left: 3px; + margin-top: 2px; + } +.ui-icon-fastar:before { content: "\f005"; } +.ui-icon-star-empty:before { content: "\f006"; } +.ui-icon-user:before { content: "\f007"; margin-left: 4px; } +.ui-icon-film:before { content: "\f008"; margin-left: 2px; } +.ui-icon-th-large:before { content: "\f009"; margin-left: 2px; margin-top: 2px; } +.ui-icon-th:before { content: "\f00a"; margin-left: 3px; margin-top: 2px; } +.ui-icon-th-list:before { content: "\f00b"; margin-left: 3px; margin-top: 2px; } +.ui-icon-ok:before { content: "\f00c"; margin-left: 2px; } +.ui-icon-remove:before { content: "\f00d"; margin-left: 3px; margin-top: 2px; } +.ui-icon-zoom-in:before { content: "\f00e"; } + +.ui-icon-zoom-out:before { content: "\f010"; } +.ui-icon-off:before { content: "\f011"; } +.ui-icon-signal:before { content: "\f012"; margin-left: -1px; } +.ui-icon-cog:before { content: "\f013"; margin-left: 3px; margin-top: 2px; } +.ui-icon-trash:before { content: "\f014"; } +.ui-icon-fahome:before { content: "\f015"; } +.ui-icon-file:before { content: "\f016"; } +.ui-icon-time:before { content: "\f017"; margin-top: 2px; } +.ui-icon-road:before { content: "\f018"; } +.ui-icon-download-alt:before { content: "\f019"; } +.ui-icon-download:before { content: "\f01a"; margin-top: 2px; } +.ui-icon-upload:before { content: "\f01b"; margin-top: 2px; } +.ui-icon-inbox:before { content: "\f01c"; } +.ui-icon-play-circle:before { content: "\f01d"; margin-top: 2px; } +.ui-icon-repeat:before { content: "\f01e"; margin-top: 2px; } + +/* \f020 is not a valid unicode character. all shifted one down */ +.ui-icon-farefresh:before { content: "\f021"; margin-top: 2px; } +.ui-icon-list-alt:before { content: "\f022"; margin-left: 3px; margin-top: 2px; } +.ui-icon-lock:before { content: "\f023"; } +.ui-icon-flag:before { content: "\f024"; margin-top: 2px; } +.ui-icon-headphones:before { content: "\f025"; } +.ui-icon-volume-off:before { content: "\f026"; } +.ui-icon-volume-down:before { content: "\f027"; } +.ui-icon-volume-up:before { content: "\f028"; } +.ui-icon-qrcode:before { content: "\f029"; } +.ui-icon-barcode:before { content: "\f02a"; } +.ui-icon-tag:before { content: "\f02b"; } +.ui-icon-tags:before { content: "\f02c"; } +.ui-icon-book:before { content: "\f02d"; } +.ui-icon-bookmark:before { content: "\f02e"; } +.ui-icon-print:before { content: "\f02f"; } + +.ui-icon-camera:before { content: "\f030"; } +.ui-icon-font:before { content: "\f031"; margin-left: 2px; } +.ui-icon-bold:before { content: "\f032"; margin-left: 2px; } +.ui-icon-italic:before { content: "\f033"; } +.ui-icon-text-height:before { content: "\f034"; } +.ui-icon-text-width:before { content: "\f035"; } +.ui-icon-align-left:before { content: "\f036"; } +.ui-icon-align-center:before { content: "\f037"; } +.ui-icon-align-right:before { content: "\f038"; } +.ui-icon-align-justify:before { content: "\f039"; } +.ui-icon-list:before { content: "\f03a"; } +.ui-icon-indent-left:before { content: "\f03b"; margin-left: 0px; margin-top: 2px; } +.ui-icon-indent-right:before { content: "\f03c"; } +.ui-icon-facetime-video:before { content: "\f03d"; } +.ui-icon-picture:before { content: "\f03e"; } + +.ui-icon-pencil:before { content: "\f040"; } +.ui-icon-map-marker:before { content: "\f041"; margin-left: 3px; margin-top: 2px; } +.ui-icon-adjust:before { content: "\f042"; margin-top: 2px; } +.ui-icon-tint:before { content: "\f043"; } +.ui-icon-edit:before { content: "\f044"; } +.ui-icon-share:before { content: "\f045"; } +.ui-icon-facheck:before { content: "\f046"; } +.ui-icon-move:before { content: "\f047"; } +.ui-icon-step-backward:before { content: "\f048"; } +.ui-icon-fast-backward:before { content: "\f049"; } +.ui-icon-backward:before { content: "\f04a"; } +.ui-icon-play:before { content: "\f04b"; margin-left: 6px; margin-top: 2px; } +.ui-icon-pause:before { content: "\f04c"; margin-top: 2px; } +.ui-icon-stop:before { content: "\f04d"; margin-top: 2px; } +.ui-icon-faforward:before { content: "\f04e"; } + +.ui-icon-fast-forward:before { content: "\f050"; } +.ui-icon-step-forward:before { content: "\f051"; } +.ui-icon-eject:before { content: "\f052"; } +.ui-icon-chevron-left:before { content: "\f053"; margin-top: 2px; } +.ui-icon-chevron-right:before { content: "\f054"; margin-top: 2px; } +.ui-icon-plus-sign:before { content: "\f055"; margin-top: 2px; } +.ui-icon-minus-sign:before { content: "\f056"; margin-top: 2px; } +.ui-icon-remove-sign:before { content: "\f057"; margin-top: 2px; } +.ui-icon-ok-sign:before { content: "\f058"; margin-top: 2px; } +.ui-icon-question-sign:before { content: "\f059"; margin-top: 2px; } +.ui-icon-info-sign:before { content: "\f05a"; margin-top: 2px; } +.ui-icon-screenshot:before { content: "\f05b"; } +.ui-icon-remove-circle:before { content: "\f05c"; margin-top: 2px; } +.ui-icon-ok-circle:before { content: "\f05d"; margin-top: 2px; } +.ui-icon-ban-circle:before { content: "\f05e"; margin-top: 2px; } + +.ui-icon-arrow-left:before { content: "\f060"; } +.ui-icon-arrow-right:before { content: "\f061"; } +.ui-icon-arrow-up:before { content: "\f062"; } +.ui-icon-arrow-down:before { content: "\f063"; } +.ui-icon-share-alt:before { content: "\f064"; } +.ui-icon-resize-full:before { content: "\f065"; } +.ui-icon-resize-small:before { content: "\f066"; } +.ui-icon-faplus:before { content: "\f067"; } +.ui-icon-faminus:before { content: "\f068"; } +.ui-icon-asterisk:before { content: "\f069"; margin-top: 2px; } +.ui-icon-exclamation-sign:before { content: "\f06a"; margin-top: 2px; } +.ui-icon-gift:before { content: "\f06b"; } +.ui-icon-leaf:before { content: "\f06c"; } +.ui-icon-fire:before { content: "\f06d"; } +.ui-icon-eye-open:before { content: "\f06e"; } + +.ui-icon-eye-close:before { content: "\f070"; } +.ui-icon-warning-sign:before { content: "\f071"; } +.ui-icon-plane:before { content: "\f072"; } +.ui-icon-calendar:before { content: "\f073"; } +.ui-icon-random:before { content: "\f074"; } +.ui-icon-comment:before { content: "\f075"; margin-top: 2px; } +.ui-icon-magnet:before { content: "\f076"; margin-top: 2px; } +.ui-icon-chevron-up:before { content: "\f077"; } +.ui-icon-chevron-down:before { content: "\f078"; } +.ui-icon-retweet:before { content: "\f079"; } +.ui-icon-shopping-cart:before { content: "\f07a"; } +.ui-icon-folder-close:before { content: "\f07b"; } +.ui-icon-folder-open:before { content: "\f07c"; } +.ui-icon-resize-vertical:before { content: "\f07d"; } +.ui-icon-resize-horizontal:before { content: "\f07e"; } + +.ui-icon-bar-chart:before { content: "\f080"; } +.ui-icon-twitter-sign:before { content: "\f081"; } +.ui-icon-facebook-sign:before { content: "\f082"; } +.ui-icon-camera-retro:before { content: "\f083"; } +.ui-icon-key:before { content: "\f084"; } +.ui-icon-cogs:before { content: "\f085"; } +.ui-icon-comments:before { content: "\f086"; } +.ui-icon-thumbs-up:before { content: "\f087"; } +.ui-icon-thumbs-down:before { content: "\f088"; } +.ui-icon-star-half:before { content: "\f089"; } +.ui-icon-heart-empty:before { content: "\f08a"; margin-top: 2px; } +.ui-icon-signout:before { content: "\f08b"; } +.ui-icon-linkedin-sign:before { content: "\f08c"; } +.ui-icon-pushpin:before { content: "\f08d"; } +.ui-icon-external-link:before { content: "\f08e"; } + +.ui-icon-signin:before { content: "\f090"; } +.ui-icon-trophy:before { content: "\f091"; } +.ui-icon-github-sign:before { content: "\f092"; } +.ui-icon-upload-alt:before { content: "\f093"; } +.ui-icon-lemon:before { content: "\f094"; } +.ui-icon-phone:before { content: "\f095"; } +.ui-icon-check-empty:before { content: "\f096"; } +.ui-icon-bookmark-empty:before { content: "\f097"; } +.ui-icon-phone-sign:before { content: "\f098"; } +.ui-icon-twitter:before { content: "\f099"; } +.ui-icon-facebook:before { content: "\f09a"; } +.ui-icon-github:before { content: "\f09b"; margin-top: 2px; } +.ui-icon-unlock:before { content: "\f09c"; } +.ui-icon-credit-card:before { content: "\f09d"; } +.ui-icon-rss:before { content: "\f09e"; } + +.ui-icon-hdd:before { content: "\f0a0"; } +.ui-icon-bullhorn:before { content: "\f0a1"; } +.ui-icon-bell:before { content: "\f0a2"; } +.ui-icon-certificate:before { content: "\f0a3"; margin-top: 2px; } +.ui-icon-hand-right:before { content: "\f0a4"; } +.ui-icon-hand-left:before { content: "\f0a5"; } +.ui-icon-hand-up:before { content: "\f0a6"; } +.ui-icon-hand-down:before { content: "\f0a7"; } +.ui-icon-circle-arrow-left:before { content: "\f0a8"; margin-top: 2px; } +.ui-icon-circle-arrow-right:before { content: "\f0a9"; margin-top: 2px; } +.ui-icon-circle-arrow-up:before { content: "\f0aa"; margin-top: 2px; } +.ui-icon-circle-arrow-down:before { content: "\f0ab"; margin-top: 2px; } +.ui-icon-globe:before { content: "\f0ac"; margin-top: 2px; } +.ui-icon-wrench:before { content: "\f0ad"; } +.ui-icon-tasks:before { content: "\f0ae"; } + +.ui-icon-filter:before { content: "\f0b0"; } +.ui-icon-briefcase:before { content: "\f0b1"; } +.ui-icon-fullscreen:before { content: "\f0b2"; } + +.ui-icon-group:before { content: "\f0c0"; } +.ui-icon-link:before { content: "\f0c1"; } +.ui-icon-cloud:before { content: "\f0c2"; } +.ui-icon-beaker:before { content: "\f0c3"; } +.ui-icon-cut:before { content: "\f0c4"; } +.ui-icon-copy:before { content: "\f0c5"; } +.ui-icon-paper-clip:before { content: "\f0c6"; } +.ui-icon-save:before { content: "\f0c7"; } +.ui-icon-sign-blank:before { content: "\f0c8"; } +.ui-icon-reorder:before { content: "\f0c9"; } +.ui-icon-list-ul:before { content: "\f0ca"; } +.ui-icon-list-ol:before { content: "\f0cb"; } +.ui-icon-strikethrough:before { content: "\f0cc"; } +.ui-icon-underline:before { content: "\f0cd"; } +.ui-icon-table:before { content: "\f0ce"; } + +.ui-icon-magic:before { content: "\f0d0"; } +.ui-icon-truck:before { content: "\f0d1"; } +.ui-icon-pinterest:before { content: "\f0d2"; margin-top: 2px; } +.ui-icon-pinterest-sign:before { content: "\f0d3"; margin-top: 2px; } +.ui-icon-google-plus-sign:before { content: "\f0d4"; } +.ui-icon-google-plus:before { content: "\f0d5"; } +.ui-icon-money:before { content: "\f0d6"; } +.ui-icon-caret-down:before { content: "\f0d7"; margin-top: 2px; } +.ui-icon-caret-up:before { content: "\f0d8"; } +.ui-icon-caret-left:before { content: "\f0d9"; margin-top: 2px; } +.ui-icon-caret-right:before { content: "\f0da"; margin-top: 2px; } +.ui-icon-columns:before { content: "\f0db"; } +.ui-icon-sort:before { content: "\f0dc"; margin-top: 2px; } +.ui-icon-sort-down:before { content: "\f0dd"; } +.ui-icon-sort-up:before { content: "\f0de"; } + +.ui-icon-envelope-alt:before { content: "\f0e0"; } +.ui-icon-linkedin:before { content: "\f0e1"; } +.ui-icon-undo:before { content: "\f0e2"; margin-top: 2px; } +.ui-icon-legal:before { content: "\f0e3"; } +.ui-icon-dashboard:before { content: "\f0e4"; } +.ui-icon-comment-alt:before { content: "\f0e5"; } +.ui-icon-comments-alt:before { content: "\f0e6"; } +.ui-icon-bolt:before { content: "\f0e7"; } +.ui-icon-sitemap:before { content: "\f0e8"; } +.ui-icon-umbrella:before { content: "\f0e9"; } +.ui-icon-paste:before { content: "\f0ea"; } + +.ui-icon-user-md:before { content: "\f200"; } diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.gif b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.gif Binary files differnew file mode 100644 index 0000000000..fd1a189c21 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.gif diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.png b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.png Binary files differnew file mode 100644 index 0000000000..13b208dddd --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/ajax-loader.png diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-black-pack.png b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-black-pack.png Binary files differnew file mode 100644 index 0000000000..07d96586cd --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-black-pack.png diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-white-pack.png b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-white-pack.png Binary files differnew file mode 100644 index 0000000000..0159f628f4 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-18-white-pack.png diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-black-pack.png b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-black-pack.png Binary files differnew file mode 100644 index 0000000000..562e839b9b --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-black-pack.png diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-white-pack.png b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-white-pack.png Binary files differnew file mode 100644 index 0000000000..81f082a4ad --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/images/icons-36-white-pack.png diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/index.html b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/index.html new file mode 100644 index 0000000000..19239a30f0 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/index.html @@ -0,0 +1,112 @@ +<!-- + jQuery Mobile Icon Pack + /index.html +--> +<!doctype html> +<html> +<head> + <title> jQuery Mobile Icon Pack</title> + + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + + <!-- jQuery Mobile CSS bits --> + <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" /> + + <!-- if you have a custom theme, add it here --> + <link rel="stylesheet" href="jqm-icon-pack-2.0-original.css" /> + + <!-- Javascript includes --> + <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script> + <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script> +</head> +<body> + <div data-role="page"> + + <div data-role="header"> + <a href="../index.html" data-icon="home">Back</a> + <h1>jQuery Mobile Icon Pack</h1> + </div> + + <div data-role="content"> + + <a href="https://github.com/commadelimited/jQuery-Mobile-Icon-Pack" data-theme="b" data-role="button">Download the Icon Pack</a> + + <div data-role="collapsible-set" data-theme="c" data-content-theme="c"> + + <h3>Standard Buttons</h3> + + <label> <input type="checkbox" name="checkbox-1 "/> I'm a checkbox</label> + <fieldset data-role="controlgroup"> + <legend>Choose a pet:</legend> + <input type="radio" name="radio-pet-1a" id="radio-pet-1a" value="choice-1" checked="checked" /> + <label for="radio-pet-1a">Option 1</label> + + <input type="radio" name="radio-pet-1a" id="radio-pet-2a" value="choice-2" /> + <label for="radio-pet-2a">Option 2</label> + </fieldset> + + <a href="index.html" data-role="button" data-icon="arrow-l">data-icon="arrow-l"</a> + <a href="index.html" data-role="button" data-icon="arrow-r">data-icon="arrow-r"</a> + <a href="index.html" data-role="button" data-icon="arrow-u">data-icon="arrow-u"</a> + <a href="index.html" data-role="button" data-icon="arrow-d">data-icon="arrow-d"</a> + <a href="index.html" data-role="button" data-icon="delete">data-icon="delete"</a> + <a href="index.html" data-role="button" data-icon="plus">data-icon="plus"</a> + <a href="index.html" data-role="button" data-icon="minus">data-icon="minus"</a> + <a href="index.html" data-role="button" data-icon="check">data-icon="check"</a> + <a href="index.html" data-role="button" data-icon="gear">data-icon="gear"</a> + <a href="index.html" data-role="button" data-icon="refresh">data-icon="refresh"</a> + <a href="index.html" data-role="button" data-icon="forward">data-icon="forward"</a> + <a href="index.html" data-role="button" data-icon="back">data-icon="back"</a> + <a href="index.html" data-role="button" data-icon="grid">data-icon="grid"</a> + <a href="index.html" data-role="button" data-icon="star">data-icon="star"</a> + <a href="index.html" data-role="button" data-icon="alert">data-icon="alert"</a> + <a href="index.html" data-role="button" data-icon="info">data-icon="info"</a> + <a href="index.html" data-role="button" data-icon="home">data-icon="home"</a> + <a href="index.html" data-role="button" data-icon="search">data-icon="search"</a> + + <h3>Extended Buttons</h3> + <a href="index.html" data-role="button" data-icon="email">data-icon="email"</a> + <a href="index.html" data-role="button" data-icon="page">data-icon="page"</a> + <a href="index.html" data-role="button" data-icon="question">data-icon="question"</a> + <a href="index.html" data-role="button" data-icon="foursquare">data-icon="foursquare"</a> + <a href="index.html" data-role="button" data-icon="twitter">data-icon="twitter"</a> + <a href="index.html" data-role="button" data-icon="facebook">data-icon="facebook"</a> + <a href="index.html" data-role="button" data-icon="dollar">data-icon="dollar"</a> + <a href="index.html" data-role="button" data-icon="euro">data-icon="euro"</a> + <a href="index.html" data-role="button" data-icon="pound">data-icon="pound"</a> + <a href="index.html" data-role="button" data-icon="apple">data-icon="apple"</a> + <a href="index.html" data-role="button" data-icon="chat">data-icon="chat"</a> + <a href="index.html" data-role="button" data-icon="trash">data-icon="trash"</a> + <a href="index.html" data-role="button" data-icon="bell">data-icon="bell"</a> + <a href="index.html" data-role="button" data-icon="mappin">data-icon="mappin"</a> + <a href="index.html" data-role="button" data-icon="direction">data-icon="direction"</a> + <a href="index.html" data-role="button" data-icon="heart">data-icon="heart"</a> + <a href="index.html" data-role="button" data-icon="wrench">data-icon="wrench"</a> + <a href="index.html" data-role="button" data-icon="play">data-icon="play"</a> + <a href="index.html" data-role="button" data-icon="pause">data-icon="pause"</a> + <a href="index.html" data-role="button" data-icon="stop">data-icon="stop"</a> + <a href="index.html" data-role="button" data-icon="person">data-icon="person"</a> + <a href="index.html" data-role="button" data-icon="music">data-icon="music"</a> + <a href="index.html" data-role="button" data-icon="rss">data-icon="rss"</a> + <a href="index.html" data-role="button" data-icon="wifi">data-icon="wifi"</a> + <a href="index.html" data-role="button" data-icon="phone">data-icon="phone"</a> + <a href="index.html" data-role="button" data-icon="power">data-icon="power"</a> + <a href="index.html" data-role="button" data-icon="lock">data-icon="lock"</a> + <a href="index.html" data-role="button" data-icon="flag">data-icon="flag"</a> + <a href="index.html" data-role="button" data-icon="calendar">data-icon="calendar"</a> + <a href="index.html" data-role="button" data-icon="lightning">data-icon="lightning"</a> + <a href="index.html" data-role="button" data-icon="drink">data-icon="drink"</a> + <a href="index.html" data-role="button" data-icon="android">data-icon="android"</a> + <a href="index.html" data-role="button" data-icon="edit">data-icon="edit"</a> + </div> + + </div> + + <div data-role="footer" data-theme="c"> + <p align="center">© 2013 - Andy Matthews</p> + </div> + + </div> +</body> +</html>
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/jqm-icon-pack-2.0-original.css b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/jqm-icon-pack-2.0-original.css new file mode 100644 index 0000000000..0981b9f2df --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/thirdparty/jqm-icon-pack-3.0/original/jqm-icon-pack-2.0-original.css @@ -0,0 +1,128 @@ +/* + jQuery Mobile Icon Pack + andy matthews + @commadelimited +*/ + +/* Icons +-----------------------------------------------------------------------------------------------------------*/ + +.ui-icon, +.ui-icon-searchfield:after { + background: #666666; + background: rgba(0,0,0,.4); + background-image: url('images/icons-18-white-pack.png'); + background-repeat: no-repeat; + -moz-border-radius: 9px; + -webkit-border-radius: 9px; + border-radius: 9px; +} + + +/* Alt icon color +-----------------------------------------------------------------------------------------------------------*/ + +.ui-icon-alt { + background: #ffffff; + background: rgba(255,255,255,.3); + background-image: url('images/icons-18-black-pack.png'); + background-repeat: no-repeat; +} + +/* restore default loading image */ +.ui-icon-loading { + background: url('images/ajax-loader.gif'); + background-size: 46px 46px; +} + +/* HD/"retina" sprite +-----------------------------------------------------------------------------------------------------------*/ + +@media only screen and (-webkit-min-device-pixel-ratio: 1.3), + only screen and (-o-min-device-pixel-ratio: 3/2), + only screen and (min--moz-device-pixel-ratio: 1.3), + only screen and (min-device-pixel-ratio: 1.3), + only screen and (min-resolution: 1.3dppx) { + + .ui-icon-plus, .ui-icon-minus, .ui-icon-delete, .ui-icon-arrow-r, + .ui-icon-arrow-l, .ui-icon-arrow-u, .ui-icon-arrow-d, .ui-icon-check, + .ui-icon-gear, .ui-icon-refresh, .ui-icon-forward, .ui-icon-back, + .ui-icon-grid, .ui-icon-star, .ui-icon-alert, .ui-icon-info, .ui-icon-home, .ui-icon-search, .ui-icon-searchfield:after, + .ui-icon-checkbox-off, .ui-icon-checkbox-on, .ui-icon-radio-off, .ui-icon-radio-on, .ui-icon-email , .ui-icon-page, + .ui-icon-question , .ui-icon-foursquare , .ui-icon-twitter , .ui-icon-facebook , .ui-icon-dollar , .ui-icon-euro, + .ui-icon-pound , .ui-icon-apple , .ui-icon-chat , .ui-icon-trash , .ui-icon-bell , .ui-icon-mappin , .ui-icon-direction, + .ui-icon-heart , .ui-icon-wrench , .ui-icon-play , .ui-icon-pause , .ui-icon-stop , .ui-icon-person , .ui-icon-music, + .ui-icon-rss , .ui-icon-wifi , .ui-icon-phone , .ui-icon-power , .ui-icon-lock , .ui-icon-flag , .ui-icon-calendar, + .ui-icon-lightning , .ui-icon-drink , .ui-icon-android , .ui-icon-edit { + background-image: url('images/icons-36-white-pack.png'); + -moz-background-size: 774px 54px; + -o-background-size: 774px 54px; + -webkit-background-size: 774px 54px; + background-size: 774px 54px; + } + .ui-icon-alt { + background-image: url('images/icons-36-black-pack.png' ); + } +} + +/* first row */ +.ui-icon-plus { background-position: -0 -0; } +.ui-icon-minus { background-position: -36px -0; } +.ui-icon-delete { background-position: -72px -0; } +.ui-icon-arrow-r { background-position: -108px -0; } +.ui-icon-arrow-l { background-position: -144px -0; } +.ui-icon-arrow-u { background-position: -180px -0; } +.ui-icon-arrow-d { background-position: -216px -0; } +.ui-icon-check { background-position: -252px -0; } +.ui-icon-gear { background-position: -288px -0; } +.ui-icon-refresh { background-position: -324px -0; } +.ui-icon-forward { background-position: -360px -0; } +.ui-icon-back { background-position: -396px -0; } +.ui-icon-grid { background-position: -432px -0; } +.ui-icon-star { background-position: -468px -0; } +.ui-icon-alert { background-position: -504px -0; } +.ui-icon-info { background-position: -540px -0; } +.ui-icon-home { background-position: -576px -0; } +.ui-icon-search,.ui-icon-searchfield:after { background-position: -612px -0; } +.ui-icon-checkbox-off { background-position: -684px -0; } +.ui-icon-checkbox-on { background-position: -648px -0; } +.ui-icon-radio-off { background-position: -756px -0; } +.ui-icon-radio-on { background-position: -718px -0; } + +/* begin icon pack definitions */ +/* second row */ +.ui-icon-email { background-position: -0 -18px; } +.ui-icon-page { background-position: -36px -18px; } +.ui-icon-question { background-position: -72px -18px; } +.ui-icon-foursquare { background-position: -108px -18px; } +.ui-icon-twitter { background-position: -144px -18px; } +.ui-icon-facebook { background-position: -180px -18px; } +.ui-icon-dollar { background-position: -216px -18px; } +.ui-icon-euro { background-position: -252px -18px; } +.ui-icon-pound { background-position: -288px -18px; } +.ui-icon-apple { background-position: -324px -18px; } +.ui-icon-chat { background-position: -360px -18px; } +.ui-icon-trash { background-position: -396px -18px; } +.ui-icon-bell { background-position: -432px -18px; } +.ui-icon-mappin { background-position: -468px -18px;} +.ui-icon-direction { background-position: -504px -18px; } +.ui-icon-heart { background-position: -540px -18px; } +.ui-icon-wrench { background-position: -576px -18px; } +.ui-icon-play { background-position: -612px -18px; } +.ui-icon-pause { background-position: -648px -18px; } +.ui-icon-stop { background-position: -684px -18px; } +.ui-icon-person { background-position: -720px -18px; } +.ui-icon-music { background-position: -756px -18px; } + +/* third row */ +.ui-icon-rss { background-position: -0 -36px; } +.ui-icon-wifi { background-position: -36px -36px; } +.ui-icon-phone { background-position: -72px -36px; } +.ui-icon-power { background-position: -108px -36px; } +.ui-icon-lock { background-position: -144px -36px; } +.ui-icon-flag { background-position: -180px -36px; } +.ui-icon-calendar { background-position: -216px -36px; } +.ui-icon-lightning { background-position: -252px -36px; } +.ui-icon-drink { background-position: -288px -36px; } +.ui-icon-android { background-position: -324px -36px; } +.ui-icon-edit { background-position: -360px -36px; } diff --git a/MediaBrowser.WebDashboard/Html/uiSettings.html b/MediaBrowser.WebDashboard/Html/uiSettings.html new file mode 100644 index 0000000000..40f65fd6c9 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/uiSettings.html @@ -0,0 +1,65 @@ +<!DOCTYPE html> +<html> +<head> + <title>Display Settings</title> +</head> +<body> + <div id="displaySettingsPage" data-role="page" class="page type-interior"> + + <div data-role="content"> + <div class="content-primary"> + <form id="displaySettingsForm"> + + <ul data-role="listview" class="ulForm"> + <li> + <label for="txtWeatherLocation">Weather location: </label> + <input id="txtWeatherLocation" name="txtWeatherLocation" type="text" onchange="DisplaySettingsPage.submit();" /> + <div class="fieldDescription"> + US zip code / City, State, Country / City, Country + </div> + </li> + <li> + <label for="selectWeatherUnit">Weather display unit: </label> + <select id="selectWeatherUnit" name="selectWeatherUnit" onchange="DisplaySettingsPage.submit();"> + <option value="Celsius">Celsius</option> + <option value="Fahrenheit">Fahrenheit</option> + </select> + </li> + <li> + <label for="txtMinResumePct">Min resume percentage: </label> + <input type="number" id="txtMinResumePct" name="txtMinResumePct" pattern="[0-9]*" required="required" min="0" max="100" onchange="DisplaySettingsPage.submit();" /> + <div class="fieldDescription"> + Titles are assumed unplayed before this time + </div> + </li> + <li> + <label for="txtMaxResumePct">Max resume percentage: </label> + <input type="number" id="txtMaxResumePct" name="txtMaxResumePct" pattern="[0-9]*" required="required" min="1" max="100" onchange="DisplaySettingsPage.submit();" /> + <div class="fieldDescription"> + Titles are assumed fully played after this time + </div> + </li> + <li> + <label for="txtMinResumeDuration">Min resume duration (seconds): </label> + <input type="number" id="txtMinResumeDuration" name="txtMinResumeDuration" pattern="[0-9]*" required="required" min="0" onchange="DisplaySettingsPage.submit();" /> + <div class="fieldDescription"> + Titles shorter than this will not be resumable + </div> + </li> + <li style="display: none;"> + <button type="submit" data-theme="b" data-icon="ok" class="btnSubmit"> + Save + </button> + </li> + </ul> + + </form> + </div> + </div> + + <script type="text/javascript"> + $('#displaySettingsForm').on('submit', DisplaySettingsPage.onSubmit); + </script> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/updatePassword.html b/MediaBrowser.WebDashboard/Html/updatePassword.html new file mode 100644 index 0000000000..b07bd16913 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/updatePassword.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> +<head> + <title></title> +</head> +<body> + <div id="updatePasswordPage" data-role="page" class="page type-interior userProfilesConfigurationPage"> + + <div data-role="content"> + <div class="content-primary"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> + <a href="#" onclick="Dashboard.navigate('editUser.html', true);" data-role="button">Profile</a> + <a href="#" data-role="button" onclick="Dashboard.navigate('userImage.html', true);">Image</a> + <a href="#" data-role="button" class="ui-btn-active">Password</a> + <a href="#" data-role="button" onclick="Dashboard.navigate('library.html', true);">Media Library</a> + </div> + <form id="updatePasswordForm"> + <ul data-role="listview" class="ulForm"> + <li> + <label for="txtCurrentPassword">Current password: </label> + <input type="password" id="txtCurrentPassword" name="txtCurrentPassword" /> + </li> + <li> + <label for="txtNewPassword">New password: </label> + <input type="password" id="txtNewPassword" name="txtNewPassword" /> + <div class="fieldDescription"> + Numeric pin codes are recommended for quicker entry with a remote. + </div> + </li> + <li> + <label for="txtNewPasswordConfirm">New password confirm: </label> + <input type="password" id="txtNewPasswordConfirm" name="txtNewPasswordConfirm" /> + </li> + <li> + <button type="submit" data-theme="b" data-icon="ok"> + Save + </button> + <div id="btnResetPassword" style="display: none;"> + <button type="button" data-theme="a" data-icon="lock" onclick="UpdatePasswordPage.resetPassword();"> + Reset Password + </button> + </div> + </li> + </ul> + </form> + </div> + </div> + <script type="text/javascript"> + $('#updatePasswordForm').on('submit', UpdatePasswordPage.onSubmit); + </script> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/userImage.html b/MediaBrowser.WebDashboard/Html/userImage.html new file mode 100644 index 0000000000..c28d2129ef --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/userImage.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> +<head> + <title> </title> +</head> +<body> + <div id="userImagePage" data-role="page" class="page type-interior userProfilesConfigurationPage"> + + <div data-role="content"> + <div class="content-primary"> + <div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true"> + <a href="#" onclick="Dashboard.navigate('editUser.html', true);" data-role="button">Profile</a> + <a href="#" data-role="button" class="ui-btn-active">Image</a> + <a href="#" data-role="button" onclick="Dashboard.navigate('updatePassword.html', true);">Password</a> + <a href="#" data-role="button" onclick="Dashboard.navigate('library.html', true);">Media Library</a> + </div> + <div class="readOnlyContent"> + <p id="fldImage"></p> + <p id="fldDeleteImage" style="display: none;"> + <button id="btnDeleteImage" type="button" data-icon="delete" onclick="UserImagePage.deleteImage();"> + Delete Image + </button> + </p> + </div> + + <h2 id="headerUploadNewImage" style="display: none;">Upload New Image</h2> + <form id="uploadUserImageForm"> + <ul data-role="listview" class="ulForm"> + <li id="fldNewImage"> + <p>1:1 Aspect Ratio Recommended</p> + <input type="file" accept="image/*" id="uploadUserImage" name="uploadUserImage" onchange="UserImagePage.onFileUploadChange(this);" /> + + <div id="userImageDropZone" class="imageDropZone"> + <h3>Drop Image Here (Chrome / Firefox / Safari)</h3> + <output id="userImageOutput"></output> + </div> + + </li> + <li id="fldNewImagePreview"></li> + <li id="fldUpload" style="display: none;"> + <button type="submit" data-icon="picture">Upload</button> + </li> + </ul> + </form> + + </div> + </div> + <script type="text/javascript"> + $('#uploadUserImageForm').on('submit', UserImagePage.onSubmit); + </script> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/userProfiles.html b/MediaBrowser.WebDashboard/Html/userProfiles.html new file mode 100644 index 0000000000..d94cfd7cb5 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/userProfiles.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> +<head> + <title>User Profiles</title> +</head> +<body> + <div id="userProfilesPage" data-role="page" class="page type-interior userProfilesConfigurationPage"> + + <div data-role="content"> + <div class="content-primary"> + <div class="readOnlyContent"> + <p id="pAddUser"> + <button type="button" data-icon="plus" onclick="Dashboard.navigate('editUser.html');"> + Add User + </button> + </p> + + <ul id="ulUserProfiles" data-role="listview" data-inset="true" data-auto-enhanced="false" data-split-icon="minus"></ul> + </div> + </div> + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/wizardFinish.html b/MediaBrowser.WebDashboard/Html/wizardFinish.html new file mode 100644 index 0000000000..06650c4f8a --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/wizardFinish.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<head> + <title>Media Browser</title> +</head> +<body> + <div id="wizardFinishPage" data-role="page" class="page standalonePage wizardPage"> + + <div data-role="content"> + + <div class="ui-corner-all ui-shadow wizardContent"> + <h2> + <img src="css/images/checkmarkblack.png" />You're Done!</h2> + + <p>That's all we need for now. Media Browser has begun collecting information about your media library. You do not need to wait for this process to complete before using a client application or changing other settings within the Dashboard.</p> + + <div class="wizardNavigation"> + <button type="button" data-iconpos="left" data-icon="arrow-left" data-inline="true" onclick="history.back();">Previous</button> + <button type="button" data-iconpos="right" data-icon="wrench" data-inline="true" onclick="Dashboard.navigate('dashboard.html');" data-theme="b">Go to the Dashboard</button> + </div> + </div> + + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/wizardLibrary.html b/MediaBrowser.WebDashboard/Html/wizardLibrary.html new file mode 100644 index 0000000000..8d34287e95 --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/wizardLibrary.html @@ -0,0 +1,60 @@ +<!DOCTYPE html> +<html> +<head> + <title>Media Browser</title> +</head> +<body> + <div id="wizardLibraryPage" data-role="page" class="page standalonePage wizardPage mediaLibraryPage"> + + <div data-role="content"> + + <div class="ui-corner-all ui-shadow wizardContent"> + <h2> + <img src="css/images/movieFolder.png" />Media Library</h2> + + <p id="fldUseDefaultLibrary" style="display: none;"> + <input type="checkbox" id="chkUseDefaultLibrary" name="chkUseDefaultLibrary" onchange="MediaLibraryPage.setUseDefaultMediaLibrary(this.checked);" /> + <label for="chkUseDefaultLibrary">Use default media library</label> + </p> + <div id="divMediaLibrary"> + <p>Below are your media collections. Expand a collection to add or remove media locations assigned to it.</p> + <p> + <button type="button" data-icon="plus" onclick="MediaLibraryPage.addVirtualFolder();">Add media collection</button> + </p> + <div id="divVirtualFolders"></div> + </div> + + <div data-role="popup" id="popupEnterText" class="ui-corner-all popup"> + + <div class="ui-corner-top ui-bar-a" style="text-align: center; padding: 0 20px;"> + <h3>Rename</h3> + </div> + + <div data-role="content" class="ui-corner-bottom ui-content"> + <form id="textEntryForm"> + <label for="txtValue">New name:</label> + <input type="text" name="txtValue" id="txtValue" required="required" /> + + <p> + <button type="submit" data-theme="b" data-icon="ok"> + Ok + </button> + <button type="button" data-icon="delete" onclick="$(this).parents('.popup').popup('close');"> + Cancel + </button> + </p> + </form> + </div> + + </div> + + <div class="wizardNavigation"> + <button type="button" data-iconpos="left" data-icon="arrow-left" data-inline="true" onclick="history.back();">Previous</button> + <button type="button" data-iconpos="right" data-icon="arrow-right" data-inline="true" onclick="Dashboard.navigate('wizardFinish.html');">Next</button> + </div> + </div> + + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/wizardStart.html b/MediaBrowser.WebDashboard/Html/wizardStart.html new file mode 100644 index 0000000000..7b4edcb8ff --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/wizardStart.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> +<head> + <title>Media Browser</title> +</head> +<body> + <div id="wizardStartPage" data-role="page" class="page standalonePage wizardPage"> + + <div data-role="content"> + + <div class="ui-corner-all ui-shadow wizardContent"> + <h2> + <img src="css/images/cloudNetwork.png" />Welcome to Media Browser Server!</h2> + + <p>This wizard will help guide you through the setup process.</p> + <div class="wizardNavigation"> + <button type="button" data-iconpos="right" data-icon="arrow-right" data-inline="true" onclick="WizardStartPage.gotoNextPage();">Next</button> + </div> + </div> + + </div> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/Html/wizardUser.html b/MediaBrowser.WebDashboard/Html/wizardUser.html new file mode 100644 index 0000000000..db49bcb6ff --- /dev/null +++ b/MediaBrowser.WebDashboard/Html/wizardUser.html @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html> +<head> + <title>Media Browser</title> +</head> +<body> + <div id="wizardUserPage" data-role="page" class="page standalonePage wizardPage"> + + <div data-role="content"> + + <div class="ui-corner-all ui-shadow wizardContent"> + <form id="wizardUserForm"> + <h2> + <img src="css/images/currentUserDefaultBlack.png" style="height: 30px;" />Tell Us About Yourself</h2> + + <p>Media Browser includes built-in support for user profiles, enabling each user to have their own display settings, playstate and ratings.</p> + + <ul data-role="listview" class="ulForm"> + <li> + <label for="txtUsername">Your first name: </label> + <input type="text" id="txtUsername" name="txtUsername" required="required" /> + <div class="fieldDescription"> + More users can be added later within the Dashboard. + </div> + </li> + </ul> + + <div class="wizardNavigation"> + <button type="button" data-iconpos="left" data-icon="arrow-left" data-inline="true" onclick="history.back();">Previous</button> + <button type="submit" data-iconpos="right" data-icon="arrow-right" data-inline="true">Next</button> + </div> + </form> + </div> + + </div> + + <script type="text/javascript"> + $('#wizardUserForm').on('submit', WizardUserPage.onSubmit); + </script> + </div> +</body> +</html> diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj index 7f1015591b..4e2ee0c669 100644 --- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj +++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj @@ -1,70 +1,413 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{5624B7B5-B5A7-41D8-9F10-CC5611109619}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>MediaBrowser.WebDashboard</RootNamespace>
- <AssemblyName>MediaBrowser.WebDashboard</AssemblyName>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup>
- <RunPostBuildEvent>Always</RunPostBuildEvent>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="System.ComponentModel.Composition" />
- <Reference Include="System.Core" />
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Plugin.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj">
- <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project>
- <Name>MediaBrowser.Common</Name>
- </ProjectReference>
- <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj">
- <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project>
- <Name>MediaBrowser.Model</Name>
- </ProjectReference>
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <PropertyGroup>
- <PostBuildEvent>xcopy "$(TargetPath)" "$(SolutionDir)\ProgramData-Server\Plugins\" /y</PostBuildEvent>
- </PropertyGroup>
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
+<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{5624B7B5-B5A7-41D8-9F10-CC5611109619}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>MediaBrowser.WebDashboard</RootNamespace> + <AssemblyName>MediaBrowser.WebDashboard</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir> + <RestorePackages>true</RestorePackages> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup> + <RunPostBuildEvent>Always</RunPostBuildEvent> + </PropertyGroup> + <ItemGroup> + <Reference Include="ServiceStack, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\ServiceStack.3.9.37\lib\net35\ServiceStack.dll</HintPath> + </Reference> + <Reference Include="ServiceStack.Common, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Common.dll</HintPath> + </Reference> + <Reference Include="ServiceStack.Interfaces, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Interfaces.dll</HintPath> + </Reference> + <Reference Include="ServiceStack.OrmLite, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\ServiceStack.OrmLite.SqlServer.3.9.37\lib\ServiceStack.OrmLite.dll</HintPath> + </Reference> + <Reference Include="ServiceStack.OrmLite.SqlServer, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\ServiceStack.OrmLite.SqlServer.3.9.37\lib\ServiceStack.OrmLite.SqlServer.dll</HintPath> + </Reference> + <Reference Include="ServiceStack.Redis, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\ServiceStack.Redis.3.9.37\lib\net35\ServiceStack.Redis.dll</HintPath> + </Reference> + <Reference Include="ServiceStack.ServiceInterface, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\ServiceStack.3.9.37\lib\net35\ServiceStack.ServiceInterface.dll</HintPath> + </Reference> + <Reference Include="ServiceStack.Text, Version=3.9.37.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll</HintPath> + </Reference> + <Reference Include="System" /> + <Reference Include="System.ComponentModel.Composition" /> + <Reference Include="System.Core" /> + <Reference Include="System.Runtime.Serialization" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Api\DashboardInfo.cs" /> + <Compile Include="Api\DashboardService.cs" /> + <Compile Include="Api\DashboardInfoWebSocketListener.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj"> + <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project> + <Name>MediaBrowser.Common</Name> + </ProjectReference> + <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj"> + <Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project> + <Name>MediaBrowser.Controller</Name> + </ProjectReference> + <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj"> + <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project> + <Name>MediaBrowser.Model</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\index.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\advanced.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\dashboard.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\Site.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\site.css" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\library.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\metadata.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\userProfiles.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\plugins.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\login.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\logindefault.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\uiSettings.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\editUser.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\favicon.ico" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\touchicon.png" /> + <EmbeddedResource Include="Html\css\images\touchicon114.png" /> + <EmbeddedResource Include="Html\css\images\touchicon72.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\iossplash.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\updatePassword.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\userImage.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\IndexPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\mblogowhitefull.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\mblogoblackfull.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\defaultCollectionImage.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\toolsWhite.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\currentUserDefaultWhite.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\rightArrow.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\userFlyoutDefault.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\MediaLibraryPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\DisplaySettingsPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\PluginsPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\MetadataConfigurationPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\LoginPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\UpdatePasswordPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\AdvancedConfigurationPage.js" /> + <EmbeddedResource Include="Html\scripts\EditUserPage.js" /> + <EmbeddedResource Include="Html\scripts\UserImagePage.js" /> + <EmbeddedResource Include="Html\scripts\UserProfilesPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\advancedMetadata.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\AdvancedMetadataConfigurationPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\pluginUpdates.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\PluginUpdatesPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\addPlugin.html" /> + <EmbeddedResource Include="Html\scripts\AddPluginPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\bg.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\pluginCatalog.html" /> + <EmbeddedResource Include="Html\scripts\PluginCatalogPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\leftArrowBlack.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\leftArrowWhite.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\currentUserDefaultBlack.png" /> + <EmbeddedResource Include="Html\css\images\toolsBlack.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scheduledTasks.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\ScheduledTasksPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scheduledTask.html" /> + <EmbeddedResource Include="Html\scripts\ScheduledTaskPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\wizardStart.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\wizardFinish.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\wizardUser.html" /> + <EmbeddedResource Include="Html\wizardLibrary.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\WizardStartPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\WizardUserPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\cloudNetwork.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\movieFolder.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\checkmarkblack.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\log.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\LogPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\metadataImages.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\MetadataImagesPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\DashboardPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\checkMarkGreen.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\clients\html5.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\clients\android.png" /> + <EmbeddedResource Include="Html\css\images\clients\ios.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\clients\mb.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\clients\windowsrt.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\clients\windowsphone.png" /> + <EmbeddedResource Include="Html\css\images\clients\win8.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\notifications\download.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\Extensions.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\support.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\SupporterPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\supporter.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\suppbadge.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\premiumflag.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\supporterKey.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\SupporterKeyPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\donatepp.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\faicons-v2.png" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\faicons.png" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\images\ajax-loader.png" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\images\icons-18-black-pack.png" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\images\icons-18-white-pack.png" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\images\icons-36-black-pack.png" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\images\icons-36-white-pack.png" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\index.html" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\jqm-icon-pack-3.0.0-fa.css" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\original\images\ajax-loader.gif" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\original\images\ajax-loader.png" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\original\images\icons-18-black-pack.png" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\original\images\icons-18-white-pack.png" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\original\images\icons-36-black-pack.png" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\original\images\icons-36-white-pack.png" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\original\index.html" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\original\jqm-icon-pack-2.0-original.css" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\font\fontawesome-webfont.eot" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\font\fontawesome-webfont.ttf" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\font\fontawesome-webfont.woff" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\font\FontAwesome.otf" /> + <EmbeddedResource Include="Html\thirdparty\jqm-icon-pack-3.0\font-awesome\jqm-icon-pack-3.0.0-fa.scss" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\registerpp.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\home.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\notifications\done.png" /> + <EmbeddedResource Include="Html\css\images\notifications\error.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\notifications\cancelled.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\notifications\info.png" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\itemDetails.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\scripts\ItemDetailPage.js" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Html\css\images\media\playCircle.png" /> + <EmbeddedResource Include="Html\css\images\media\nextTrack.png" /> + <EmbeddedResource Include="Html\css\images\media\pause.png" /> + <EmbeddedResource Include="Html\css\images\media\play.png" /> + <EmbeddedResource Include="Html\css\images\media\previousTrack.png" /> + <EmbeddedResource Include="Html\css\images\media\stop.png" /> + <EmbeddedResource Include="Html\css\images\itemDetails\videoDefault.png" /> + <EmbeddedResource Include="Html\css\images\itemDetails\audioDefault.png" /> + <EmbeddedResource Include="Html\css\images\itemDetails\gameDefault.png" /> + <Content Include="Html\css\images\stars.png" /> + <EmbeddedResource Include="Html\scripts\MediaPlayer.js" /> + </ItemGroup> + <ItemGroup> + <None Include="packages.config" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <PropertyGroup> + <PostBuildEvent>xcopy "$(TargetPath)" "$(SolutionDir)\MediaBrowser.ServerApplication\" /y</PostBuildEvent> + </PropertyGroup> + <Import Project="$(SolutionDir)\.nuget\nuget.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> </Project>
\ No newline at end of file diff --git a/MediaBrowser.WebDashboard/Plugin.cs b/MediaBrowser.WebDashboard/Plugin.cs deleted file mode 100644 index 95727a06fc..0000000000 --- a/MediaBrowser.WebDashboard/Plugin.cs +++ /dev/null @@ -1,15 +0,0 @@ -using MediaBrowser.Common.Plugins;
-using MediaBrowser.Model.Plugins;
-using System.ComponentModel.Composition;
-
-namespace MediaBrowser.WebDashboard
-{
- [Export(typeof(BasePlugin))]
- public class Plugin : BasePlugin
- {
- public override string Name
- {
- get { return "Dashboard"; }
- }
- }
-}
diff --git a/MediaBrowser.WebDashboard/Properties/AssemblyInfo.cs b/MediaBrowser.WebDashboard/Properties/AssemblyInfo.cs index a33fd44622..b9ce4d0aef 100644 --- a/MediaBrowser.WebDashboard/Properties/AssemblyInfo.cs +++ b/MediaBrowser.WebDashboard/Properties/AssemblyInfo.cs @@ -1,35 +1,34 @@ -using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("MediaBrowser.WebDashboard")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("MediaBrowser.WebDashboard")]
-[assembly: AssemblyCopyright("Copyright © 2012")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("c6c73d12-933d-4389-be56-e59973c9ed00")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MediaBrowser.WebDashboard")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MediaBrowser.WebDashboard")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c6c73d12-933d-4389-be56-e59973c9ed00")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("2.9.*")] diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config new file mode 100644 index 0000000000..ea25110aae --- /dev/null +++ b/MediaBrowser.WebDashboard/packages.config @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="ServiceStack" version="3.9.37" targetFramework="net45" /> + <package id="ServiceStack.Common" version="3.9.37" targetFramework="net45" /> + <package id="ServiceStack.OrmLite.SqlServer" version="3.9.37" targetFramework="net45" /> + <package id="ServiceStack.Redis" version="3.9.37" targetFramework="net45" /> + <package id="ServiceStack.Text" version="3.9.37" targetFramework="net45" /> +</packages>
\ No newline at end of file |
