浏览代码

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

Luke Pulverenti 12 年之前
父节点
当前提交
b20151fff3
共有 100 个文件被更改,包括 375 次插入3910 次删除
  1. 27 4
      MediaBrowser.Api/BaseApiService.cs
  2. 2 2
      MediaBrowser.Api/Images/ImageService.cs
  3. 1 1
      MediaBrowser.Api/Playback/BaseStreamingService.cs
  4. 1 1
      MediaBrowser.Api/Playback/Hls/AudioHlsService.cs
  5. 1 1
      MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
  6. 3 3
      MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
  7. 1 1
      MediaBrowser.Api/PluginService.cs
  8. 1 1
      MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
  9. 4 4
      MediaBrowser.Api/UserLibrary/UserLibraryService.cs
  10. 1 1
      MediaBrowser.Api/UserService.cs
  11. 9 1
      MediaBrowser.Model/Configuration/ServerConfiguration.cs
  12. 14 18
      MediaBrowser.Server.Implementations/HttpServer/BaseRestService.cs
  13. 10 1
      MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs
  14. 5 6
      MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs
  15. 3 0
      MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
  16. 64 27
      MediaBrowser.WebDashboard/Api/DashboardService.cs
  17. 228 5
      MediaBrowser.WebDashboard/ApiClient.js
  18. 0 4
      MediaBrowser.WebDashboard/Html/Readme.txt
  19. 0 36
      MediaBrowser.WebDashboard/Html/about.html
  20. 0 83
      MediaBrowser.WebDashboard/Html/addPlugin.html
  21. 0 64
      MediaBrowser.WebDashboard/Html/advanced.html
  22. 0 40
      MediaBrowser.WebDashboard/Html/advancedMetadata.html
  23. 二进制
      MediaBrowser.WebDashboard/Html/css/images/bg.png
  24. 二进制
      MediaBrowser.WebDashboard/Html/css/images/checkMarkGreen.png
  25. 二进制
      MediaBrowser.WebDashboard/Html/css/images/checkmarkblack.png
  26. 二进制
      MediaBrowser.WebDashboard/Html/css/images/clients/android.png
  27. 二进制
      MediaBrowser.WebDashboard/Html/css/images/clients/dlna.png
  28. 二进制
      MediaBrowser.WebDashboard/Html/css/images/clients/html5.png
  29. 二进制
      MediaBrowser.WebDashboard/Html/css/images/clients/ios.png
  30. 二进制
      MediaBrowser.WebDashboard/Html/css/images/clients/mb.png
  31. 二进制
      MediaBrowser.WebDashboard/Html/css/images/clients/win8.png
  32. 二进制
      MediaBrowser.WebDashboard/Html/css/images/clients/windowsphone.png
  33. 二进制
      MediaBrowser.WebDashboard/Html/css/images/clients/windowsrt.png
  34. 二进制
      MediaBrowser.WebDashboard/Html/css/images/cloudNetwork.png
  35. 二进制
      MediaBrowser.WebDashboard/Html/css/images/currentUserDefaultBlack.png
  36. 二进制
      MediaBrowser.WebDashboard/Html/css/images/currentUserDefaultWhite.png
  37. 二进制
      MediaBrowser.WebDashboard/Html/css/images/defaultCollectionImage.png
  38. 二进制
      MediaBrowser.WebDashboard/Html/css/images/donatepp.png
  39. 二进制
      MediaBrowser.WebDashboard/Html/css/images/home.png
  40. 二进制
      MediaBrowser.WebDashboard/Html/css/images/iossplash.png
  41. 二进制
      MediaBrowser.WebDashboard/Html/css/images/itemDetails/audioDefault.png
  42. 二进制
      MediaBrowser.WebDashboard/Html/css/images/itemDetails/gameDefault.png
  43. 二进制
      MediaBrowser.WebDashboard/Html/css/images/itemDetails/videoDefault.png
  44. 二进制
      MediaBrowser.WebDashboard/Html/css/images/leftArrowBlack.png
  45. 二进制
      MediaBrowser.WebDashboard/Html/css/images/leftArrowWhite.png
  46. 二进制
      MediaBrowser.WebDashboard/Html/css/images/logindefault.png
  47. 二进制
      MediaBrowser.WebDashboard/Html/css/images/mblogoicon.png
  48. 二进制
      MediaBrowser.WebDashboard/Html/css/images/mblogotextblack.png
  49. 二进制
      MediaBrowser.WebDashboard/Html/css/images/mblogotextwhite.png
  50. 二进制
      MediaBrowser.WebDashboard/Html/css/images/media/nextTrack.png
  51. 二进制
      MediaBrowser.WebDashboard/Html/css/images/media/pause.png
  52. 二进制
      MediaBrowser.WebDashboard/Html/css/images/media/play.png
  53. 二进制
      MediaBrowser.WebDashboard/Html/css/images/media/playCircle.png
  54. 二进制
      MediaBrowser.WebDashboard/Html/css/images/media/previousTrack.png
  55. 二进制
      MediaBrowser.WebDashboard/Html/css/images/media/stop.png
  56. 二进制
      MediaBrowser.WebDashboard/Html/css/images/movieFolder.png
  57. 二进制
      MediaBrowser.WebDashboard/Html/css/images/notifications/cancelled.png
  58. 二进制
      MediaBrowser.WebDashboard/Html/css/images/notifications/done.png
  59. 二进制
      MediaBrowser.WebDashboard/Html/css/images/notifications/download.png
  60. 二进制
      MediaBrowser.WebDashboard/Html/css/images/notifications/error.png
  61. 二进制
      MediaBrowser.WebDashboard/Html/css/images/notifications/info.png
  62. 二进制
      MediaBrowser.WebDashboard/Html/css/images/premiumflag.png
  63. 二进制
      MediaBrowser.WebDashboard/Html/css/images/registerpp.png
  64. 二进制
      MediaBrowser.WebDashboard/Html/css/images/rightArrow.png
  65. 二进制
      MediaBrowser.WebDashboard/Html/css/images/stars.png
  66. 二进制
      MediaBrowser.WebDashboard/Html/css/images/suppbadge.png
  67. 二进制
      MediaBrowser.WebDashboard/Html/css/images/supporterflag.png
  68. 二进制
      MediaBrowser.WebDashboard/Html/css/images/toolsBlack.png
  69. 二进制
      MediaBrowser.WebDashboard/Html/css/images/toolsWhite.png
  70. 二进制
      MediaBrowser.WebDashboard/Html/css/images/touchicon.png
  71. 二进制
      MediaBrowser.WebDashboard/Html/css/images/touchicon114.png
  72. 二进制
      MediaBrowser.WebDashboard/Html/css/images/touchicon72.png
  73. 二进制
      MediaBrowser.WebDashboard/Html/css/images/userFlyoutDefault.png
  74. 0 729
      MediaBrowser.WebDashboard/Html/css/site.css
  75. 0 57
      MediaBrowser.WebDashboard/Html/dashboard.html
  76. 0 63
      MediaBrowser.WebDashboard/Html/editUser.html
  77. 二进制
      MediaBrowser.WebDashboard/Html/favicon.ico
  78. 0 33
      MediaBrowser.WebDashboard/Html/index.html
  79. 0 66
      MediaBrowser.WebDashboard/Html/itemDetails.html
  80. 0 23
      MediaBrowser.WebDashboard/Html/itemList.html
  81. 0 57
      MediaBrowser.WebDashboard/Html/library.html
  82. 0 31
      MediaBrowser.WebDashboard/Html/log.html
  83. 0 39
      MediaBrowser.WebDashboard/Html/login.html
  84. 0 56
      MediaBrowser.WebDashboard/Html/metadata.html
  85. 0 164
      MediaBrowser.WebDashboard/Html/metadataImages.html
  86. 0 22
      MediaBrowser.WebDashboard/Html/pluginCatalog.html
  87. 0 34
      MediaBrowser.WebDashboard/Html/pluginUpdates.html
  88. 0 24
      MediaBrowser.WebDashboard/Html/plugins.html
  89. 0 90
      MediaBrowser.WebDashboard/Html/scheduledTask.html
  90. 0 18
      MediaBrowser.WebDashboard/Html/scheduledTasks.html
  91. 0 249
      MediaBrowser.WebDashboard/Html/scripts/AddPluginPage.js
  92. 0 65
      MediaBrowser.WebDashboard/Html/scripts/AdvancedConfigurationPage.js
  93. 0 69
      MediaBrowser.WebDashboard/Html/scripts/AdvancedMetadataConfigurationPage.js
  94. 0 462
      MediaBrowser.WebDashboard/Html/scripts/DashboardPage.js
  95. 0 46
      MediaBrowser.WebDashboard/Html/scripts/DisplaySettingsPage.js
  96. 0 175
      MediaBrowser.WebDashboard/Html/scripts/EditUserPage.js
  97. 0 506
      MediaBrowser.WebDashboard/Html/scripts/Extensions.js
  98. 0 106
      MediaBrowser.WebDashboard/Html/scripts/IndexPage.js
  99. 0 376
      MediaBrowser.WebDashboard/Html/scripts/ItemDetailPage.js
  100. 0 46
      MediaBrowser.WebDashboard/Html/scripts/ItemListPage.js

+ 27 - 4
MediaBrowser.Api/BaseApiService.cs

@@ -63,9 +63,32 @@ namespace MediaBrowser.Api
         public static Dictionary<string, string> GetAuthorization(IHttpRequest httpReq)
         public static Dictionary<string, string> GetAuthorization(IHttpRequest httpReq)
         {
         {
             var auth = httpReq.Headers[HttpHeaders.Authorization];
             var auth = httpReq.Headers[HttpHeaders.Authorization];
-            if (auth == null) return null;
 
 
-            var parts = auth.Split(' ');
+            return GetAuthorization(auth);
+        }
+
+        /// <summary>
+        /// Gets the authorization.
+        /// </summary>
+        /// <param name="httpReq">The HTTP req.</param>
+        /// <returns>Dictionary{System.StringSystem.String}.</returns>
+        public static Dictionary<string, string> GetAuthorization(IRequestContext httpReq)
+        {
+            var auth = httpReq.GetHeader("Authorization");
+
+            return GetAuthorization(auth);
+        }
+        
+        /// <summary>
+        /// Gets the authorization.
+        /// </summary>
+        /// <param name="authorizationHeader">The authorization header.</param>
+        /// <returns>Dictionary{System.StringSystem.String}.</returns>
+        private static Dictionary<string, string> GetAuthorization(string authorizationHeader)
+        {
+            if (authorizationHeader == null) return null;
+
+            var parts = authorizationHeader.Split(' ');
 
 
             // There should be at least to parts
             // There should be at least to parts
             if (parts.Length < 2) return null;
             if (parts.Length < 2) return null;
@@ -77,8 +100,8 @@ namespace MediaBrowser.Api
             }
             }
 
 
             // Remove uptil the first space
             // Remove uptil the first space
-            auth = auth.Substring(auth.IndexOf(' '));
-            parts = auth.Split(',');
+            authorizationHeader = authorizationHeader.Substring(authorizationHeader.IndexOf(' '));
+            parts = authorizationHeader.Split(',');
 
 
             var result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
             var result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
 
 

+ 2 - 2
MediaBrowser.Api/Images/ImageService.cs

@@ -250,14 +250,14 @@ namespace MediaBrowser.Api.Images
         /// <param name="request">The request.</param>
         /// <param name="request">The request.</param>
         public void Post(PostUserImage request)
         public void Post(PostUserImage request)
         {
         {
-            var pathInfo = PathInfo.Parse(Request.PathInfo);
+            var pathInfo = PathInfo.Parse(RequestContext.PathInfo);
             var id = new Guid(pathInfo.GetArgumentValue<string>(1));
             var id = new Guid(pathInfo.GetArgumentValue<string>(1));
 
 
             request.Type = (ImageType)Enum.Parse(typeof(ImageType), pathInfo.GetArgumentValue<string>(3), true);
             request.Type = (ImageType)Enum.Parse(typeof(ImageType), pathInfo.GetArgumentValue<string>(3), true);
 
 
             var item = _userManager.Users.First(i => i.Id == id);
             var item = _userManager.Users.First(i => i.Id == id);
 
 
-            var task = PostImage(item, request.RequestStream, request.Type, Request.ContentType);
+            var task = PostImage(item, request.RequestStream, request.Type, RequestContext.ContentType);
 
 
             Task.WaitAll(task);
             Task.WaitAll(task);
         }
         }

+ 1 - 1
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -624,7 +624,7 @@ namespace MediaBrowser.Api.Playback
 
 
             var media = (IHasMediaStreams)item;
             var media = (IHasMediaStreams)item;
 
 
-            var url = Request.PathInfo;
+            var url = RequestContext.PathInfo;
 
 
             if (!request.AudioCodec.HasValue)
             if (!request.AudioCodec.HasValue)
             {
             {

+ 1 - 1
MediaBrowser.Api/Playback/Hls/AudioHlsService.cs

@@ -40,7 +40,7 @@ namespace MediaBrowser.Api.Playback.Hls
 
 
         public object Get(GetHlsAudioSegment request)
         public object Get(GetHlsAudioSegment request)
         {
         {
-            var file = SegmentFilePrefix + request.SegmentId + Path.GetExtension(Request.PathInfo);
+            var file = SegmentFilePrefix + request.SegmentId + Path.GetExtension(RequestContext.PathInfo);
 
 
             file = Path.Combine(ApplicationPaths.EncodedMediaCachePath, file);
             file = Path.Combine(ApplicationPaths.EncodedMediaCachePath, file);
 
 

+ 1 - 1
MediaBrowser.Api/Playback/Hls/VideoHlsService.cs

@@ -32,7 +32,7 @@ namespace MediaBrowser.Api.Playback.Hls
 
 
         public object Get(GetHlsVideoSegment request)
         public object Get(GetHlsVideoSegment request)
         {
         {
-            var file = SegmentFilePrefix + request.SegmentId + Path.GetExtension(Request.PathInfo);
+            var file = SegmentFilePrefix + request.SegmentId + Path.GetExtension(RequestContext.PathInfo);
 
 
             file = Path.Combine(ApplicationPaths.EncodedMediaCachePath, file);
             file = Path.Combine(ApplicationPaths.EncodedMediaCachePath, file);
 
 

+ 3 - 3
MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs

@@ -87,15 +87,15 @@ namespace MediaBrowser.Api.Playback.Progressive
         /// </summary>
         /// </summary>
         private bool AddDlnaHeaders(StreamState state)
         private bool AddDlnaHeaders(StreamState state)
         {
         {
-            var headers = Request.Headers;
+            var timeSeek = RequestContext.GetHeader("TimeSeekRange.dlna.org");
 
 
-            if (!string.IsNullOrEmpty(headers["TimeSeekRange.dlna.org"]))
+            if (!string.IsNullOrEmpty(timeSeek))
             {
             {
                 Response.StatusCode = 406;
                 Response.StatusCode = 406;
                 return false;
                 return false;
             }
             }
 
 
-            var transferMode = headers["transferMode.dlna.org"];
+            var transferMode = RequestContext.GetHeader("transferMode.dlna.org");
             Response.AddHeader("transferMode.dlna.org", string.IsNullOrEmpty(transferMode) ? "Streaming" : transferMode);
             Response.AddHeader("transferMode.dlna.org", string.IsNullOrEmpty(transferMode) ? "Streaming" : transferMode);
 
 
             var contentFeatures = string.Empty;
             var contentFeatures = string.Empty;

+ 1 - 1
MediaBrowser.Api/PluginService.cs

@@ -252,7 +252,7 @@ namespace MediaBrowser.Api
         {
         {
             // We need to parse this manually because we told service stack not to with IRequiresRequestStream
             // We need to parse this manually because we told service stack not to with IRequiresRequestStream
             // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
             // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
-            var pathInfo = PathInfo.Parse(Request.PathInfo);
+            var pathInfo = PathInfo.Parse(RequestContext.PathInfo);
             var id = new Guid(pathInfo.GetArgumentValue<string>(1));
             var id = new Guid(pathInfo.GetArgumentValue<string>(1));
 
 
             var plugin = _appHost.Plugins.First(p => p.Id == id);
             var plugin = _appHost.Plugins.First(p => p.Id == id);

+ 1 - 1
MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs

@@ -182,7 +182,7 @@ namespace MediaBrowser.Api.ScheduledTasks
         {
         {
             // We need to parse this manually because we told service stack not to with IRequiresRequestStream
             // We need to parse this manually because we told service stack not to with IRequiresRequestStream
             // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
             // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
-            var pathInfo = PathInfo.Parse(Request.PathInfo);
+            var pathInfo = PathInfo.Parse(RequestContext.PathInfo);
             var id = new Guid(pathInfo.GetArgumentValue<string>(1));
             var id = new Guid(pathInfo.GetArgumentValue<string>(1));
 
 
             var task = TaskManager.ScheduledTasks.FirstOrDefault(i => i.Id == id);
             var task = TaskManager.ScheduledTasks.FirstOrDefault(i => i.Id == id);

+ 4 - 4
MediaBrowser.Api/UserLibrary/UserLibraryService.cs

@@ -474,7 +474,7 @@ namespace MediaBrowser.Api.UserLibrary
         {
         {
             // We need to parse this manually because we told service stack not to with IRequiresRequestStream
             // We need to parse this manually because we told service stack not to with IRequiresRequestStream
             // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
             // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
-            var pathInfo = PathInfo.Parse(Request.PathInfo);
+            var pathInfo = PathInfo.Parse(RequestContext.PathInfo);
             var userId = new Guid(pathInfo.GetArgumentValue<string>(1));
             var userId = new Guid(pathInfo.GetArgumentValue<string>(1));
             var itemId = pathInfo.GetArgumentValue<string>(3);
             var itemId = pathInfo.GetArgumentValue<string>(3);
 
 
@@ -595,7 +595,7 @@ namespace MediaBrowser.Api.UserLibrary
 
 
             var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
             var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
-            var auth = RequestFilterAttribute.GetAuthorization(Request);
+            var auth = RequestFilterAttribute.GetAuthorization(RequestContext);
 
 
             if (auth != null)
             if (auth != null)
             {
             {
@@ -613,7 +613,7 @@ namespace MediaBrowser.Api.UserLibrary
 
 
             var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
             var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
-            var auth = RequestFilterAttribute.GetAuthorization(Request);
+            var auth = RequestFilterAttribute.GetAuthorization(RequestContext);
 
 
             if (auth != null)
             if (auth != null)
             {
             {
@@ -633,7 +633,7 @@ namespace MediaBrowser.Api.UserLibrary
 
 
             var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
             var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
 
 
-            var auth = RequestFilterAttribute.GetAuthorization(Request);
+            var auth = RequestFilterAttribute.GetAuthorization(RequestContext);
 
 
             if (auth != null)
             if (auth != null)
             {
             {

+ 1 - 1
MediaBrowser.Api/UserService.cs

@@ -274,7 +274,7 @@ namespace MediaBrowser.Api
         {
         {
             // We need to parse this manually because we told service stack not to with IRequiresRequestStream
             // We need to parse this manually because we told service stack not to with IRequiresRequestStream
             // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
             // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
-            var pathInfo = PathInfo.Parse(Request.PathInfo);
+            var pathInfo = PathInfo.Parse(RequestContext.PathInfo);
             var id = new Guid(pathInfo.GetArgumentValue<string>(1));
             var id = new Guid(pathInfo.GetArgumentValue<string>(1));
 
 
             var dtoUser = request;
             var dtoUser = request;

+ 9 - 1
MediaBrowser.Model/Configuration/ServerConfiguration.cs

@@ -261,7 +261,15 @@ namespace MediaBrowser.Model.Configuration
         [ProtoMember(57)]
         [ProtoMember(57)]
         public bool EnableDeveloperTools { get; set; }
         public bool EnableDeveloperTools { get; set; }
 
 
-        // Next Proto number ====> 61
+        /// <summary>
+        /// Gets or sets a value indicating whether [enable dashboard response caching].
+        /// Allows potential contributors without visual studio to modify production dashboard code and test changes.
+        /// </summary>
+        /// <value><c>true</c> if [enable dashboard response caching]; otherwise, <c>false</c>.</value>
+        [ProtoMember(61)]
+        public bool EnableDashboardResponseCaching { get; set; }
+        
+        // Next Proto number ====> 62
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="ServerConfiguration" /> class.
         /// Initializes a new instance of the <see cref="ServerConfiguration" /> class.

+ 14 - 18
MediaBrowser.Server.Implementations/HttpServer/BaseRestService.cs

@@ -1,5 +1,4 @@
-using System.Net;
-using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
@@ -11,7 +10,7 @@ using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Globalization;
 using System.IO;
 using System.IO;
-using System.Linq;
+using System.Net;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
 using MimeTypes = MediaBrowser.Common.Net.MimeTypes;
 using MimeTypes = MediaBrowser.Common.Net.MimeTypes;
 
 
@@ -27,7 +26,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         /// </summary>
         /// </summary>
         /// <value>The logger.</value>
         /// <value>The logger.</value>
         public ILogger Logger { get; set; }
         public ILogger Logger { get; set; }
-        
+
         /// <summary>
         /// <summary>
         /// Gets a value indicating whether this instance is range request.
         /// Gets a value indicating whether this instance is range request.
         /// </summary>
         /// </summary>
@@ -36,7 +35,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         {
         {
             get
             get
             {
             {
-                return Request.Headers.AllKeys.Contains("Range");
+                return !string.IsNullOrEmpty(RequestContext.GetHeader("Range"));
             }
             }
         }
         }
 
 
@@ -55,8 +54,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
                 throw new ArgumentNullException("result");
                 throw new ArgumentNullException("result");
             }
             }
             
             
-            Response.AddHeader("Vary", "Accept-Encoding");
-
             return RequestContext.ToOptimizedResult(result);
             return RequestContext.ToOptimizedResult(result);
         }
         }
 
 
@@ -200,11 +197,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 
 
             var compress = ShouldCompressResponse(contentType);
             var compress = ShouldCompressResponse(contentType);
 
 
-            if (compress)
-            {
-                Response.AddHeader("Vary", "Accept-Encoding");
-            }
-
             return ToStaticResult(contentType, factoryFn, compress, headersOnly).Result;
             return ToStaticResult(contentType, factoryFn, compress, headersOnly).Result;
         }
         }
 
 
@@ -266,9 +258,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 
 
                 if (IsRangeRequest)
                 if (IsRangeRequest)
                 {
                 {
-                    return new RangeRequestWriter(Request.Headers, httpListenerResponse, stream, headersOnly);
+                    return new RangeRequestWriter(RequestContext.GetHeader("Range"), httpListenerResponse, stream, headersOnly);
                 }
                 }
-
+             
                 httpListenerResponse.ContentLength64 = stream.Length;
                 httpListenerResponse.ContentLength64 = stream.Length;
                 return headersOnly ? null : new StreamWriter(stream, Logger);
                 return headersOnly ? null : new StreamWriter(stream, Logger);
             }
             }
@@ -332,22 +324,26 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         {
         {
             var isNotModified = true;
             var isNotModified = true;
 
 
-            if (Request.Headers.AllKeys.Contains("If-Modified-Since"))
+            var ifModifiedSinceHeader = RequestContext.GetHeader("If-Modified-Since");
+
+            if (!string.IsNullOrEmpty(ifModifiedSinceHeader))
             {
             {
                 DateTime ifModifiedSince;
                 DateTime ifModifiedSince;
 
 
-                if (DateTime.TryParse(Request.Headers["If-Modified-Since"], out ifModifiedSince))
+                if (DateTime.TryParse(ifModifiedSinceHeader, out ifModifiedSince))
                 {
                 {
                     isNotModified = IsNotModified(ifModifiedSince.ToUniversalTime(), cacheDuration, lastDateModified);
                     isNotModified = IsNotModified(ifModifiedSince.ToUniversalTime(), cacheDuration, lastDateModified);
                 }
                 }
             }
             }
 
 
+            var ifNoneMatchHeader = RequestContext.GetHeader("If-None-Match");
+            
             // Validate If-None-Match
             // Validate If-None-Match
-            if (isNotModified && (cacheKey.HasValue || !string.IsNullOrEmpty(Request.Headers["If-None-Match"])))
+            if (isNotModified && (cacheKey.HasValue || !string.IsNullOrEmpty(ifNoneMatchHeader)))
             {
             {
                 Guid ifNoneMatch;
                 Guid ifNoneMatch;
 
 
-                if (Guid.TryParse(Request.Headers["If-None-Match"] ?? string.Empty, out ifNoneMatch))
+                if (Guid.TryParse(ifNoneMatchHeader ?? string.Empty, out ifNoneMatch))
                 {
                 {
                     if (cacheKey.HasValue && cacheKey.Value == ifNoneMatch)
                     if (cacheKey.HasValue && cacheKey.Value == ifNoneMatch)
                     {
                     {

+ 10 - 1
MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs

@@ -162,9 +162,18 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 
 
                         if (!string.IsNullOrEmpty(exception.Message))
                         if (!string.IsNullOrEmpty(exception.Message))
                         {
                         {
-                            res.AddHeader("X-Application-Error-Code", exception.Message);
+                            res.AddHeader("X-Application-Error-Code", exception.Message.Replace(Environment.NewLine, " "));
                         }
                         }
                     }
                     }
+
+                    if (dto is CompressedResult)
+                    {
+                        // Per Google PageSpeed
+                        // This instructs the proxies to cache two versions of the resource: one compressed, and one uncompressed. 
+                        // The correct version of the resource is delivered based on the client request header. 
+                        // This is a good choice for applications that are singly homed and depend on public proxies for user locality.                        
+                        res.AddHeader("Vary", "Accept-Encoding");
+                    }
                 });
                 });
         }
         }
 
 

+ 5 - 6
MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs

@@ -1,7 +1,6 @@
 using ServiceStack.Service;
 using ServiceStack.Service;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
-using System.Collections.Specialized;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Net;
 using System.Net;
@@ -17,19 +16,19 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         /// <value>The source stream.</value>
         /// <value>The source stream.</value>
         private Stream SourceStream { get; set; }
         private Stream SourceStream { get; set; }
         private HttpListenerResponse Response { get; set; }
         private HttpListenerResponse Response { get; set; }
-        private NameValueCollection RequestHeaders { get; set; }
+        private string RangeHeader { get; set; }
         private bool IsHeadRequest { get; set; }
         private bool IsHeadRequest { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="StreamWriter" /> class.
         /// Initializes a new instance of the <see cref="StreamWriter" /> class.
         /// </summary>
         /// </summary>
-        /// <param name="requestHeaders">The request headers.</param>
+        /// <param name="rangeHeader">The range header.</param>
         /// <param name="response">The response.</param>
         /// <param name="response">The response.</param>
         /// <param name="source">The source.</param>
         /// <param name="source">The source.</param>
         /// <param name="isHeadRequest">if set to <c>true</c> [is head request].</param>
         /// <param name="isHeadRequest">if set to <c>true</c> [is head request].</param>
-        public RangeRequestWriter(NameValueCollection requestHeaders, HttpListenerResponse response, Stream source, bool isHeadRequest)
+        public RangeRequestWriter(string rangeHeader, HttpListenerResponse response, Stream source, bool isHeadRequest)
         {
         {
-            RequestHeaders = requestHeaders;
+            RangeHeader = rangeHeader;
             Response = response;
             Response = response;
             SourceStream = source;
             SourceStream = source;
             IsHeadRequest = isHeadRequest;
             IsHeadRequest = isHeadRequest;
@@ -52,7 +51,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
                     _requestedRanges = new List<KeyValuePair<long, long?>>();
                     _requestedRanges = new List<KeyValuePair<long, long?>>();
 
 
                     // Example: bytes=0-,32-63
                     // Example: bytes=0-,32-63
-                    var ranges = RequestHeaders["Range"].Split('=')[1].Split(',');
+                    var ranges = RangeHeader.Split('=')[1].Split(',');
 
 
                     foreach (var range in ranges)
                     foreach (var range in ranges)
                     {
                     {

+ 3 - 0
MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj

@@ -404,6 +404,9 @@ xcopy "$(TargetDir)x86" "$(SolutionDir)..\Deploy\Server\System\x86" /y
 mkdir "$(SolutionDir)..\Deploy\Server\System\CorePlugins"
 mkdir "$(SolutionDir)..\Deploy\Server\System\CorePlugins"
 xcopy "$(TargetDir)CorePlugins" "$(SolutionDir)..\Deploy\Server\System\CorePlugins" /y
 xcopy "$(TargetDir)CorePlugins" "$(SolutionDir)..\Deploy\Server\System\CorePlugins" /y
 
 
+mkdir "$(SolutionDir)..\Deploy\Server\System\dashboard-ui"
+xcopy "$(TargetDir)dashboard-ui" "$(SolutionDir)..\Deploy\Server\System\dashboard-ui" /y
+
 del "$(SolutionDir)..\Deploy\MBServer.zip"
 del "$(SolutionDir)..\Deploy\MBServer.zip"
 "$(SolutionDir)ThirdParty\7zip\7za" a -tzip "$(SolutionDir)..\Deploy\MBServer.zip" "$(SolutionDir)..\Deploy\Server\*"
 "$(SolutionDir)ThirdParty\7zip\7za" a -tzip "$(SolutionDir)..\Deploy\MBServer.zip" "$(SolutionDir)..\Deploy\Server\*"
 )</PostBuildEvent>
 )</PostBuildEvent>

+ 64 - 27
MediaBrowser.WebDashboard/Api/DashboardService.cs

@@ -1,8 +1,10 @@
-using System.Reflection;
+using System.Diagnostics;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Plugins;
 using MediaBrowser.Controller.Plugins;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
@@ -14,7 +16,7 @@ using System.Collections.Generic;
 using System.ComponentModel.Composition;
 using System.ComponentModel.Composition;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
-using System.Net;
+using System.Reflection;
 using System.Text;
 using System.Text;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
@@ -90,20 +92,31 @@ namespace MediaBrowser.WebDashboard.Api
         /// </summary>
         /// </summary>
         private readonly IUserManager _userManager;
         private readonly IUserManager _userManager;
 
 
+        /// <summary>
+        /// The _app host
+        /// </summary>
         private readonly IServerApplicationHost _appHost;
         private readonly IServerApplicationHost _appHost;
+        /// <summary>
+        /// The _library manager
+        /// </summary>
         private readonly ILibraryManager _libraryManager;
         private readonly ILibraryManager _libraryManager;
 
 
+        private readonly IServerConfigurationManager _serverConfigurationManager;
+
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="DashboardService" /> class.
         /// Initializes a new instance of the <see cref="DashboardService" /> class.
         /// </summary>
         /// </summary>
         /// <param name="taskManager">The task manager.</param>
         /// <param name="taskManager">The task manager.</param>
         /// <param name="userManager">The user manager.</param>
         /// <param name="userManager">The user manager.</param>
-        public DashboardService(ITaskManager taskManager, IUserManager userManager, IServerApplicationHost appHost, ILibraryManager libraryManager)
+        /// <param name="appHost">The app host.</param>
+        /// <param name="libraryManager">The library manager.</param>
+        public DashboardService(ITaskManager taskManager, IUserManager userManager, IServerApplicationHost appHost, ILibraryManager libraryManager, IServerConfigurationManager serverConfigurationManager)
         {
         {
             _taskManager = taskManager;
             _taskManager = taskManager;
             _userManager = userManager;
             _userManager = userManager;
             _appHost = appHost;
             _appHost = appHost;
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
+            _serverConfigurationManager = serverConfigurationManager;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -119,9 +132,11 @@ namespace MediaBrowser.WebDashboard.Api
         /// <summary>
         /// <summary>
         /// Gets the dashboard info.
         /// Gets the dashboard info.
         /// </summary>
         /// </summary>
+        /// <param name="appHost">The app host.</param>
         /// <param name="logger">The logger.</param>
         /// <param name="logger">The logger.</param>
         /// <param name="taskManager">The task manager.</param>
         /// <param name="taskManager">The task manager.</param>
         /// <param name="userManager">The user manager.</param>
         /// <param name="userManager">The user manager.</param>
+        /// <param name="libraryManager">The library manager.</param>
         /// <returns>DashboardInfo.</returns>
         /// <returns>DashboardInfo.</returns>
         public static async Task<DashboardInfo> GetDashboardInfo(IServerApplicationHost appHost, ILogger logger, ITaskManager taskManager, IUserManager userManager, ILibraryManager libraryManager)
         public static async Task<DashboardInfo> GetDashboardInfo(IServerApplicationHost appHost, ILogger logger, ITaskManager taskManager, IUserManager userManager, ILibraryManager libraryManager)
         {
         {
@@ -188,6 +203,14 @@ namespace MediaBrowser.WebDashboard.Api
 
 
             var contentType = MimeTypes.GetMimeType(path);
             var contentType = MimeTypes.GetMimeType(path);
 
 
+            // Don't cache if not configured to do so
+            // But always cache images to simulate production
+            if (!_serverConfigurationManager.Configuration.EnableDashboardResponseCaching && !contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
+            {
+                Response.ContentType = contentType;
+                return GetResourceStream(path).Result;
+            }
+
             TimeSpan? cacheDuration = null;
             TimeSpan? cacheDuration = null;
 
 
             // Cache images unconditionally - updates to image files will require new filename
             // Cache images unconditionally - updates to image files will require new filename
@@ -199,7 +222,9 @@ namespace MediaBrowser.WebDashboard.Api
 
 
             var assembly = GetType().Assembly.GetName();
             var assembly = GetType().Assembly.GetName();
 
 
-            return ToStaticResult(assembly.Version.ToString().GetMD5(), null, cacheDuration, contentType, () => GetResourceStream(path));
+            var cacheKey = (assembly.Version + path).GetMD5();
+
+            return ToStaticResult(cacheKey, null, cacheDuration, contentType, () => GetResourceStream(path));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -217,7 +242,7 @@ namespace MediaBrowser.WebDashboard.Api
             }
             }
             else
             else
             {
             {
-                resourceStream = GetType().Assembly.GetManifestResourceStream("MediaBrowser.WebDashboard.Html." + ConvertUrlToResourcePath(path));
+                resourceStream = GetRawResourceStream(path);
             }
             }
 
 
             if (resourceStream != null)
             if (resourceStream != null)
@@ -236,32 +261,20 @@ namespace MediaBrowser.WebDashboard.Api
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// Redirects the specified CTX.
+        /// Gets the raw resource stream.
         /// </summary>
         /// </summary>
-        /// <param name="ctx">The CTX.</param>
-        /// <param name="url">The URL.</param>
-        private void Redirect(HttpListenerContext ctx, string url)
+        /// <param name="path">The path.</param>
+        /// <returns>Task{Stream}.</returns>
+        private Stream GetRawResourceStream(string path)
         {
         {
-            // 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";
+            var runningDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
 
 
-            ctx.Response.Redirect(url);
-            ctx.Response.Close();
-        }
+            path = Path.Combine(runningDirectory, "dashboard-ui", path.Replace('/', '\\'));
 
 
-        /// <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 new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, StreamDefaults.DefaultFileStreamBufferSize, true);
 
 
-            return string.IsNullOrEmpty(query) ? newUrl : newUrl + query;
+            // This code is used when the files are embedded resources
+            //return GetType().Assembly.GetManifestResourceStream("MediaBrowser.WebDashboard.Html." + ConvertUrlToResourcePath(path));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -454,13 +467,21 @@ namespace MediaBrowser.WebDashboard.Api
 
 
             foreach (var file in scriptFiles)
             foreach (var file in scriptFiles)
             {
             {
-                await AppendResource(assembly, memoryStream, resourcePrefix + file, newLineBytes).ConfigureAwait(false);
+                await AppendResource(memoryStream, "scripts/" + file, newLineBytes).ConfigureAwait(false);
             }
             }
 
 
             memoryStream.Position = 0;
             memoryStream.Position = 0;
             return memoryStream;
             return memoryStream;
         }
         }
 
 
+        /// <summary>
+        /// Appends the resource.
+        /// </summary>
+        /// <param name="assembly">The assembly.</param>
+        /// <param name="outputStream">The output stream.</param>
+        /// <param name="path">The path.</param>
+        /// <param name="newLineBytes">The new line bytes.</param>
+        /// <returns>Task.</returns>
         private async Task AppendResource(Assembly assembly, Stream outputStream, string path, byte[] newLineBytes)
         private async Task AppendResource(Assembly assembly, Stream outputStream, string path, byte[] newLineBytes)
         {
         {
             using (var stream = assembly.GetManifestResourceStream(path))
             using (var stream = assembly.GetManifestResourceStream(path))
@@ -471,6 +492,22 @@ namespace MediaBrowser.WebDashboard.Api
             }
             }
         }
         }
 
 
+        /// <summary>
+        /// Appends the resource.
+        /// </summary>
+        /// <param name="outputStream">The output stream.</param>
+        /// <param name="path">The path.</param>
+        /// <param name="newLineBytes">The new line bytes.</param>
+        /// <returns>Task.</returns>
+        private async Task AppendResource(Stream outputStream, string path, byte[] newLineBytes)
+        {
+            using (var stream = GetRawResourceStream(path))
+            {
+                await stream.CopyToAsync(outputStream).ConfigureAwait(false);
+
+                await outputStream.WriteAsync(newLineBytes, 0, newLineBytes.Length).ConfigureAwait(false);
+            }
+        }
     }
     }
 
 
 }
 }

+ 228 - 5
MediaBrowser.WebDashboard/ApiClient.js

@@ -2,7 +2,7 @@
     window.MediaBrowser = {};
     window.MediaBrowser = {};
 }
 }
 
 
-MediaBrowser.ApiClient = function ($, navigator) {
+MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
 
 
     /**
     /**
      * Creates a new api client instance
      * Creates a new api client instance
@@ -15,8 +15,9 @@ MediaBrowser.ApiClient = function ($, navigator) {
 
 
         var self = this;
         var self = this;
         var deviceName = "Web Browser";
         var deviceName = "Web Browser";
-        var deviceId = SHA1(navigator.userAgent + (navigator.cpuClass || ""));
+        var deviceId = MediaBrowser.SHA1(navigator.userAgent + (navigator.cpuClass || ""));
         var currentUserId;
         var currentUserId;
+        var webSocket;
 
 
         /**
         /**
          * Gets the server host name.
          * Gets the server host name.
@@ -88,6 +89,55 @@ MediaBrowser.ApiClient = function ($, navigator) {
             return url;
             return url;
         };
         };
 
 
+        self.openWebSocket = function (port) {
+
+            var url = "ws://" + serverHostName + ":" + port + "/mediabrowser";
+
+            webSocket = new WebSocket(url);
+
+            webSocket.onmessage = function (msg) {
+                msg = JSON.parse(msg.data);
+                $(self).trigger("websocketmessage", [msg]);
+            };
+
+            webSocket.onopen = function () {
+                setTimeout(function () {
+                    $(self).trigger("websocketopen");
+                }, 500);
+            };
+            webSocket.onerror = function () {
+                setTimeout(function () {
+                    $(self).trigger("websocketerror");
+                }, 0);
+            };
+            webSocket.onclose = function () {
+                setTimeout(function () {
+                    $(self).trigger("websocketclose");
+                }, 0);
+            };
+        };
+
+        self.sendWebSocketMessage = function (name, data) {
+
+            var msg = { MessageType: name };
+
+            if (data) {
+                msg.Data = data;
+            }
+
+            msg = JSON.stringify(msg);
+
+            webSocket.send(msg);
+        };
+
+        self.isWebSocketOpen = function () {
+            return webSocket && webSocket.readyState === WebSocket.OPEN;
+        };
+
+        self.isWebSocketOpenOrConnecting = function () {
+            return webSocket && (webSocket.readyState === WebSocket.OPEN || webSocket.readyState === WebSocket.CONNECTING);
+        };
+
         /**
         /**
          * Gets an item from the server
          * Gets an item from the server
          * Omit itemId to get the root folder.
          * Omit itemId to get the root folder.
@@ -1184,7 +1234,7 @@ MediaBrowser.ApiClient = function ($, navigator) {
             var url = self.getUrl("Users/" + userId + "/authenticate");
             var url = self.getUrl("Users/" + userId + "/authenticate");
 
 
             var postData = {
             var postData = {
-                password: SHA1(password || "")
+                password: MediaBrowser.SHA1(password || "")
             };
             };
 
 
             return self.ajax({
             return self.ajax({
@@ -1214,7 +1264,7 @@ MediaBrowser.ApiClient = function ($, navigator) {
 
 
             };
             };
 
 
-            postData.currentPassword = SHA1(currentPassword);
+            postData.currentPassword = MediaBrowser.SHA1(currentPassword);
 
 
             if (newPassword) {
             if (newPassword) {
                 postData.newPassword = newPassword;
                 postData.newPassword = newPassword;
@@ -1523,7 +1573,7 @@ MediaBrowser.ApiClient = function ($, navigator) {
         };
         };
     };
     };
 
 
-}(jQuery, navigator);
+}(jQuery, navigator, JSON, window.WebSocket, setTimeout);
 
 
 /**
 /**
  * Provides a friendly way to create an api client instance using information from the browser's current url
  * Provides a friendly way to create an api client instance using information from the browser's current url
@@ -1533,4 +1583,177 @@ MediaBrowser.ApiClient.create = function (clientName) {
     var loc = window.location;
     var loc = window.location;
 
 
     return new MediaBrowser.ApiClient(loc.protocol, loc.hostname, loc.port, clientName);
     return new MediaBrowser.ApiClient(loc.protocol, loc.hostname, loc.port, clientName);
+};
+
+/**
+*
+*  Secure Hash Algorithm (SHA1)
+*  http://www.webtoolkit.info/
+*
+**/
+MediaBrowser.SHA1 = function (msg) {
+
+    function rotate_left(n, s) {
+        var t4 = (n << s) | (n >>> (32 - s));
+        return t4;
+    };
+
+    function lsb_hex(val) {
+        var str = "";
+        var i;
+        var vh;
+        var vl;
+
+        for (i = 0; i <= 6; i += 2) {
+            vh = (val >>> (i * 4 + 4)) & 0x0f;
+            vl = (val >>> (i * 4)) & 0x0f;
+            str += vh.toString(16) + vl.toString(16);
+        }
+        return str;
+    };
+
+    function cvt_hex(val) {
+        var str = "";
+        var i;
+        var v;
+
+        for (i = 7; i >= 0; i--) {
+            v = (val >>> (i * 4)) & 0x0f;
+            str += v.toString(16);
+        }
+        return str;
+    };
+
+
+    function Utf8Encode(string) {
+        string = string.replace(/\r\n/g, "\n");
+        var utftext = "";
+
+        for (var n = 0; n < string.length; n++) {
+
+            var c = string.charCodeAt(n);
+
+            if (c < 128) {
+                utftext += String.fromCharCode(c);
+            }
+            else if ((c > 127) && (c < 2048)) {
+                utftext += String.fromCharCode((c >> 6) | 192);
+                utftext += String.fromCharCode((c & 63) | 128);
+            }
+            else {
+                utftext += String.fromCharCode((c >> 12) | 224);
+                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
+                utftext += String.fromCharCode((c & 63) | 128);
+            }
+
+        }
+
+        return utftext;
+    };
+
+    var blockstart;
+    var i, j;
+    var W = new Array(80);
+    var H0 = 0x67452301;
+    var H1 = 0xEFCDAB89;
+    var H2 = 0x98BADCFE;
+    var H3 = 0x10325476;
+    var H4 = 0xC3D2E1F0;
+    var A, B, C, D, E;
+    var temp;
+
+    msg = Utf8Encode(msg);
+
+    var msg_len = msg.length;
+
+    var word_array = new Array();
+    for (i = 0; i < msg_len - 3; i += 4) {
+        j = msg.charCodeAt(i) << 24 | msg.charCodeAt(i + 1) << 16 |
+		msg.charCodeAt(i + 2) << 8 | msg.charCodeAt(i + 3);
+        word_array.push(j);
+    }
+
+    switch (msg_len % 4) {
+        case 0:
+            i = 0x080000000;
+            break;
+        case 1:
+            i = msg.charCodeAt(msg_len - 1) << 24 | 0x0800000;
+            break;
+
+        case 2:
+            i = msg.charCodeAt(msg_len - 2) << 24 | msg.charCodeAt(msg_len - 1) << 16 | 0x08000;
+            break;
+
+        case 3:
+            i = msg.charCodeAt(msg_len - 3) << 24 | msg.charCodeAt(msg_len - 2) << 16 | msg.charCodeAt(msg_len - 1) << 8 | 0x80;
+            break;
+    }
+
+    word_array.push(i);
+
+    while ((word_array.length % 16) != 14) word_array.push(0);
+
+    word_array.push(msg_len >>> 29);
+    word_array.push((msg_len << 3) & 0x0ffffffff);
+
+
+    for (blockstart = 0; blockstart < word_array.length; blockstart += 16) {
+
+        for (i = 0; i < 16; i++) W[i] = word_array[blockstart + i];
+        for (i = 16; i <= 79; i++) W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
+
+        A = H0;
+        B = H1;
+        C = H2;
+        D = H3;
+        E = H4;
+
+        for (i = 0; i <= 19; i++) {
+            temp = (rotate_left(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
+            E = D;
+            D = C;
+            C = rotate_left(B, 30);
+            B = A;
+            A = temp;
+        }
+
+        for (i = 20; i <= 39; i++) {
+            temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
+            E = D;
+            D = C;
+            C = rotate_left(B, 30);
+            B = A;
+            A = temp;
+        }
+
+        for (i = 40; i <= 59; i++) {
+            temp = (rotate_left(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
+            E = D;
+            D = C;
+            C = rotate_left(B, 30);
+            B = A;
+            A = temp;
+        }
+
+        for (i = 60; i <= 79; i++) {
+            temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff;
+            E = D;
+            D = C;
+            C = rotate_left(B, 30);
+            B = A;
+            A = temp;
+        }
+
+        H0 = (H0 + A) & 0x0ffffffff;
+        H1 = (H1 + B) & 0x0ffffffff;
+        H2 = (H2 + C) & 0x0ffffffff;
+        H3 = (H3 + D) & 0x0ffffffff;
+        H4 = (H4 + E) & 0x0ffffffff;
+
+    }
+
+    var temp = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4);
+
+    return temp.toLowerCase();
 };
 };

+ 0 - 4
MediaBrowser.WebDashboard/Html/Readme.txt

@@ -1,4 +0,0 @@
-All static files such as html, images, etc, need to be marked as embedded resources.
-
-Here is a link for more information regarding the Build Action property.
-http://msdn.microsoft.com/en-us/library/0c6xyb66.aspx

+ 0 - 36
MediaBrowser.WebDashboard/Html/about.html

@@ -1,36 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <title>About</title>
-</head>
-<body>
-    <div id="aboutPage" 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">Supporter Key</a>
-                        <a href="about.html" data-role="button" class="ui-btn-active">About</a>
-                    </div>
-                    <p>
-                        <img class="imgLogoIcon" src="css/images/mblogoicon.png" /><img class="imgLogoText" src="css/images/mblogotextblack.png" />
-                        <br />
-                        <br />
-                        Version <span id="appVersionNumber"></span>
-                    </p>
-                    <hr/>
-                    <br/>
-                    <br/>
-                    <p>
-                        Utilizing <a href="http://www.pismotechnic.com/pfm/" target="_blank">Pismo File Mount</a> through a donated license.
-                    </p>                    
-                </div>
-            </div>
-        </div>
-    </div>
-</body>
-</html>

+ 0 - 83
MediaBrowser.WebDashboard/Html/addPlugin.html

@@ -1,83 +0,0 @@
-<!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>
-                        <div class="premiumHasPrice" style="display: none">
-                            <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>
-
-                    <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>

+ 0 - 64
MediaBrowser.WebDashboard/Html/advanced.html

@@ -1,64 +0,0 @@
-<!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="selectAutomaticUpdateLevel">Automatic update level</label>
-                            <select name="selectAutomaticUpdateLevel" id="selectAutomaticUpdateLevel">
-                                <option value="Release">Official Release</option>
-                                <option value="Beta">Beta</option>
-                                <option value="Dev">Dev</option>
-                            </select>
-                        </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>

+ 0 - 40
MediaBrowser.WebDashboard/Html/advancedMetadata.html

@@ -1,40 +0,0 @@
-<!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 style="display: none;">
-                            <button class="btnSubmit" type="submit" data-theme="b">
-                                Save
-                            </button>
-                        </li>
-                    </ul>
-                </form>
-            </div>
-
-        </div>
-
-        <script type="text/javascript">
-            $('#advancedMetadataConfigurationForm').on('submit', AdvancedMetadataConfigurationPage.onSubmit);
-        </script>
-    </div>
-</body>
-</html>

二进制
MediaBrowser.WebDashboard/Html/css/images/bg.png


二进制
MediaBrowser.WebDashboard/Html/css/images/checkMarkGreen.png


二进制
MediaBrowser.WebDashboard/Html/css/images/checkmarkblack.png


二进制
MediaBrowser.WebDashboard/Html/css/images/clients/android.png


二进制
MediaBrowser.WebDashboard/Html/css/images/clients/dlna.png


二进制
MediaBrowser.WebDashboard/Html/css/images/clients/html5.png


二进制
MediaBrowser.WebDashboard/Html/css/images/clients/ios.png


二进制
MediaBrowser.WebDashboard/Html/css/images/clients/mb.png


二进制
MediaBrowser.WebDashboard/Html/css/images/clients/win8.png


二进制
MediaBrowser.WebDashboard/Html/css/images/clients/windowsphone.png


二进制
MediaBrowser.WebDashboard/Html/css/images/clients/windowsrt.png


二进制
MediaBrowser.WebDashboard/Html/css/images/cloudNetwork.png


二进制
MediaBrowser.WebDashboard/Html/css/images/currentUserDefaultBlack.png


二进制
MediaBrowser.WebDashboard/Html/css/images/currentUserDefaultWhite.png


二进制
MediaBrowser.WebDashboard/Html/css/images/defaultCollectionImage.png


二进制
MediaBrowser.WebDashboard/Html/css/images/donatepp.png


二进制
MediaBrowser.WebDashboard/Html/css/images/home.png


二进制
MediaBrowser.WebDashboard/Html/css/images/iossplash.png


二进制
MediaBrowser.WebDashboard/Html/css/images/itemDetails/audioDefault.png


二进制
MediaBrowser.WebDashboard/Html/css/images/itemDetails/gameDefault.png


二进制
MediaBrowser.WebDashboard/Html/css/images/itemDetails/videoDefault.png


二进制
MediaBrowser.WebDashboard/Html/css/images/leftArrowBlack.png


二进制
MediaBrowser.WebDashboard/Html/css/images/leftArrowWhite.png


二进制
MediaBrowser.WebDashboard/Html/css/images/logindefault.png


二进制
MediaBrowser.WebDashboard/Html/css/images/mblogoicon.png


二进制
MediaBrowser.WebDashboard/Html/css/images/mblogotextblack.png


二进制
MediaBrowser.WebDashboard/Html/css/images/mblogotextwhite.png


二进制
MediaBrowser.WebDashboard/Html/css/images/media/nextTrack.png


二进制
MediaBrowser.WebDashboard/Html/css/images/media/pause.png


二进制
MediaBrowser.WebDashboard/Html/css/images/media/play.png


二进制
MediaBrowser.WebDashboard/Html/css/images/media/playCircle.png


二进制
MediaBrowser.WebDashboard/Html/css/images/media/previousTrack.png


二进制
MediaBrowser.WebDashboard/Html/css/images/media/stop.png


二进制
MediaBrowser.WebDashboard/Html/css/images/movieFolder.png


二进制
MediaBrowser.WebDashboard/Html/css/images/notifications/cancelled.png


二进制
MediaBrowser.WebDashboard/Html/css/images/notifications/done.png


二进制
MediaBrowser.WebDashboard/Html/css/images/notifications/download.png


二进制
MediaBrowser.WebDashboard/Html/css/images/notifications/error.png


二进制
MediaBrowser.WebDashboard/Html/css/images/notifications/info.png


二进制
MediaBrowser.WebDashboard/Html/css/images/premiumflag.png


二进制
MediaBrowser.WebDashboard/Html/css/images/registerpp.png


二进制
MediaBrowser.WebDashboard/Html/css/images/rightArrow.png


二进制
MediaBrowser.WebDashboard/Html/css/images/stars.png


二进制
MediaBrowser.WebDashboard/Html/css/images/suppbadge.png


二进制
MediaBrowser.WebDashboard/Html/css/images/supporterflag.png


二进制
MediaBrowser.WebDashboard/Html/css/images/toolsBlack.png


二进制
MediaBrowser.WebDashboard/Html/css/images/toolsWhite.png


二进制
MediaBrowser.WebDashboard/Html/css/images/touchicon.png


二进制
MediaBrowser.WebDashboard/Html/css/images/touchicon114.png


二进制
MediaBrowser.WebDashboard/Html/css/images/touchicon72.png


二进制
MediaBrowser.WebDashboard/Html/css/images/userFlyoutDefault.png


文件差异内容过多而无法显示
+ 0 - 729
MediaBrowser.WebDashboard/Html/css/site.css


+ 0 - 57
MediaBrowser.WebDashboard/Html/dashboard.html

@@ -1,57 +0,0 @@
-<!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 id="pPluginUpdates"></div>
-                        </div>
-                    </div>
-
-                    <div id="collapsiblePendingInstallations" data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em; display: none;">
-                        <h3>Pending Installations</h3>
-                        <p>The following components have been installed or updated:</p>
-                        <div id="pendingInstallations">
-                        </div>
-                        <p>Please restart the server to finish applying updates.</p>
-                        <button type="button" data-icon="refresh" data-theme="b" onclick="Dashboard.restartServer();">Restart Now</button>
-                    </div>
-
-                    <div data-role="collapsible" data-content-theme="c" data-collapsed="false" style="margin-top: 2em;">
-                        <h3>Active Users</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>

+ 0 - 63
MediaBrowser.WebDashboard/Html/editUser.html

@@ -1,63 +0,0 @@
-<!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>

二进制
MediaBrowser.WebDashboard/Html/favicon.ico


+ 0 - 33
MediaBrowser.WebDashboard/Html/index.html

@@ -1,33 +0,0 @@
-<!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>

+ 0 - 66
MediaBrowser.WebDashboard/Html/itemDetails.html

@@ -1,66 +0,0 @@
-<!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" id="galleryCollapsible">
-                <h3>Gallery</h3>
-                <div id="galleryContent"></div>
-            </div>
-        </div>
-    </div>
-</body>
-</html>

+ 0 - 23
MediaBrowser.WebDashboard/Html/itemList.html

@@ -1,23 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <title></title>
-</head>
-<body>
-    <div id="itemListPage" data-role="page" class="page libraryPage" data-theme="a">
-        <div data-role="content" class="itemListContent">
-            <div style="text-align: right;">
-                <button type="button" onclick="$( '#optionsPanel', $.mobile.activePage ).panel( 'open' );" data-mini="true" data-inline="true">Options</button>
-            </div>
-            <h1 id="itemName" class="listHeader"></h1>
-
-
-            <div id="listItems"></div>
-        </div>
-
-        <div data-role="panel" id="optionsPanel" data-position="right" data-display="overlay" data-position-fixed="true" data-theme="a">
-            <div>Panel content</div>
-        </div>
-    </div>
-</body>
-</html>

+ 0 - 57
MediaBrowser.WebDashboard/Html/library.html

@@ -1,57 +0,0 @@
-<!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>

+ 0 - 31
MediaBrowser.WebDashboard/Html/log.html

@@ -1,31 +0,0 @@
-<!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>
-                    <a href="about.html" data-role="button">About</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>

+ 0 - 39
MediaBrowser.WebDashboard/Html/login.html

@@ -1,39 +0,0 @@
-<!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 0px 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>

+ 0 - 56
MediaBrowser.WebDashboard/Html/metadata.html

@@ -1,56 +0,0 @@
-<!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" onchange="MetadataConfigurationPage.submit();" />
-                            <label for="chkEnableInternetProviders">Download metadata from the internet </label>
-                        </li>
-                        <li>
-                            <input type="checkbox" id="chkSaveLocal" name="chkSaveLocal" onchange="MetadataConfigurationPage.submit();" />
-                            <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" onchange="MetadataConfigurationPage.submit();" />
-                        </li>
-                        <li>
-                            <label for="selectLanguage">Preferred language: </label>
-                            <select name="selectLanguage" id="selectLanguage" onchange="MetadataConfigurationPage.submit();"></select>
-                        </li>
-                        <li>
-                            <label for="selectCountry">Country: </label>
-                            <select name="selectCountry" id="selectCountry" onchange="MetadataConfigurationPage.submit();"></select>
-                        </li>
-                        <li style="display: none;">
-                            <button class="btnSubmit" type="submit" data-theme="b">
-                                Save
-                            </button>
-                        </li>
-                    </ul>
-                </form>
-            </div>
-
-        </div>
-
-        <script type="text/javascript">
-            $('#metadataConfigurationForm').on('submit', MetadataConfigurationPage.onSubmit);
-        </script>
-    </div>
-</body>
-</html>

+ 0 - 164
MediaBrowser.WebDashboard/Html/metadataImages.html

@@ -1,164 +0,0 @@
-<!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" onchange="MetadataImagesPage.submit();" />
-                            <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" onchange="MetadataImagesPage.submit();" />
-                        </li>
-                    </ul>
-                    <p>Enable additional image downloading:</p>
-                    <div data-role="collapsible">
-                        <h3>Movies</h3>
-                        <div data-role="controlgroup">
-                            <input type="checkbox" data-mini="true" id="chkDownloadMovieArt" name="chkDownloadMovieArt" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadMovieArt">Movie Art</label>
-
-                            <input type="checkbox" data-mini="true" id="chkDownloadMovieBanner" name="chkDownloadMovieBanner" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadMovieBanner">Movie Banner</label>
-
-                            <input type="checkbox" data-mini="true" id="chkDownloadMovieDisc" name="chkDownloadMovieDisc" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadMovieDisc">Movie Disc</label>
-
-                            <input type="checkbox" data-mini="true" id="chkDownloadMovieLogo" name="chkDownloadMovieLogo" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadMovieLogo">Movie Logo</label>
-
-                            <input type="checkbox" data-mini="true" id="chkDownloadMovieThumb" name="chkDownloadMovieThumb" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadMovieThumb">Movie Thumb</label>
-
-
-                        </div>
-                    </div>
-
-                    <div data-role="collapsible">
-                        <h3>TV Series</h3>
-                        <div data-role="controlgroup">
-                            <input type="checkbox" data-mini="true" id="chKDownloadTVArt" name="chKDownloadTVArt" onchange="MetadataImagesPage.submit();" />
-                            <label for="chKDownloadTVArt">TV Series Art</label>
-
-                            <input type="checkbox" data-mini="true" id="chkDownloadTVBanner" name="chkDownloadTVBanner" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadTVBanner">TV Series Banner</label>
-
-                            <input type="checkbox" data-mini="true" id="chkDownloadTVLogo" name="chkDownloadTVLogo" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadTVLogo">TV Series Logo</label>
-
-                            <input type="checkbox" data-mini="true" id="chkDownloadTVThumb" name="chkDownloadTVThumb" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadTVThumb">TV Series Thumb</label>
-                        </div>
-                    </div>
-
-
-                    <div data-role="collapsible">
-                        <h3>TV Seasons</h3>
-                        <div data-role="controlgroup">
-                            <input type="checkbox" data-mini="true" id="chkDownloadSeasonBackdrops" name="chkDownloadSeasonBackdrops" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadSeasonBackdrops">TV Season Backdrops</label>
-
-                            <input type="checkbox" data-mini="true" id="chkDownloadSeasonBanner" name="chkDownloadSeasonBanner" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadSeasonBanner">TV Season Banner</label>
-
-                            <input type="checkbox" data-mini="true" id="chkDownloadSeasonThumb" name="chkDownloadSeasonThumb" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadSeasonThumb">TV Season Thumb</label>
-                        </div>
-
-                    </div>
-
-                    <div data-role="collapsible">
-                        <h3>Music Artists</h3>
-                        <div data-role="controlgroup">
-                            <input type="checkbox" data-mini="true" id="chkDownloadArtistThumb" name="chkDownloadArtistThumb" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadArtistThumb">Music Artist Thumb (primary image)</label>
-
-                            <input type="checkbox" data-mini="true" id="chkDownloadArtistBackdrops" name="chkDownloadArtistBackdrops" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadArtistBackdrops">Music Artist Backdrops</label>
-
-                            <input type="checkbox" data-mini="true" id="chkDownloadArtistLogo" name="chkDownloadArtistLogo" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadArtistLogo">Music Artist Logo</label>
-
-                            <input type="checkbox" data-mini="true" id="chkDownloadArtistBanner" name="chkDownloadArtistBanner" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadArtistBanner">Music Artist Banner</label>
-                        </div>
-
-                    </div>
-                    <div data-role="collapsible">
-                        <h3>Music Albums</h3>
-                        <div data-role="controlgroup">
-                            <input type="checkbox" data-mini="true" id="chkDownloadAlbumPrimary" name="chkDownloadAlbumPrimary" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadAlbumPrimary">Music Album Cover</label>
-
-                            <input type="checkbox" data-mini="true" id="chkDownloadAlbumBackdrops" name="chkDownloadAlbumBackdrops" onchange="MetadataImagesPage.submit();" />
-                            <label for="chkDownloadAlbumBackdrops">Music Album Backdrops</label>
-                        </div>
-
-                    </div>
-                    <br />
-                    <br />
-                    <ul data-role="listview" class="ulForm">
-                        <li>
-                            <label for="selectTmdbPosterDownloadSize">Tmdb poster download size: </label>
-                            <select id="selectTmdbPosterDownloadSize" name="selectTmdbPosterDownloadSize" onchange="MetadataImagesPage.submit();">
-                                <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" onchange="MetadataImagesPage.submit();">
-                                <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" onchange="MetadataImagesPage.submit();">
-                                <option value="original">original</option>
-                                <option value="w45">w45</option>
-                                <option value="w185">w185</option>
-                                <option value="h632">h632</option>
-                            </select>
-                        </li>
-                        <li style="display: none;">
-                            <button class="btnSubmit" type="submit" data-theme="b">
-                                Save
-                            </button>
-                        </li>
-                    </ul>
-                </form>
-            </div>
-
-        </div>
-
-        <script type="text/javascript">
-            $('#metadataImagesConfigurationForm').on('submit', MetadataImagesPage.onSubmit);
-        </script>
-    </div>
-</body>
-</html>

+ 0 - 22
MediaBrowser.WebDashboard/Html/pluginCatalog.html

@@ -1,22 +0,0 @@
-<!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>

+ 0 - 34
MediaBrowser.WebDashboard/Html/pluginUpdates.html

@@ -1,34 +0,0 @@
-<!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>

+ 0 - 24
MediaBrowser.WebDashboard/Html/plugins.html

@@ -1,24 +0,0 @@
-<!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>

+ 0 - 90
MediaBrowser.WebDashboard/Html/scheduledTask.html

@@ -1,90 +0,0 @@
-<!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>

+ 0 - 18
MediaBrowser.WebDashboard/Html/scheduledTasks.html

@@ -1,18 +0,0 @@
-<!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>

+ 0 - 249
MediaBrowser.WebDashboard/Html/scripts/AddPluginPage.js

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

+ 0 - 65
MediaBrowser.WebDashboard/Html/scripts/AdvancedConfigurationPage.js

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

+ 0 - 69
MediaBrowser.WebDashboard/Html/scripts/AdvancedMetadataConfigurationPage.js

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

+ 0 - 462
MediaBrowser.WebDashboard/Html/scripts/DashboardPage.js

@@ -1,462 +0,0 @@
-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) {
-
-        var clientLowered = connection.Client.toLowerCase();
-        
-        if (clientLowered == "dashboard") {
-
-            return "<img src='css/images/clients/html5.png' alt='Dashboard' title='Dashboard' />";
-        }
-        if (clientLowered == "media browser classic") {
-
-            return "<img src='css/images/clients/mb.png' alt='Media Browser Classic' title='Media Browser Classic' />";
-        }
-        if (clientLowered == "media browser theater") {
-
-            return "<img src='css/images/clients/mb.png' alt='Media Browser Theater' title='Media Browser Theater' />";
-        }
-        if (clientLowered == "android") {
-
-            return "<img src='css/images/clients/android.png' alt='Android' title='Android' />";
-        }
-        if (clientLowered == "ios") {
-
-            return "<img src='css/images/clients/ios.png' alt='iOS' title='iOS' />";
-        }
-        if (clientLowered == "windows rt") {
-
-            return "<img src='css/images/clients/windowsrt.png' alt='Windows RT' title='Windows RT' />";
-        }
-        if (clientLowered == "windows phone") {
-
-            return "<img src='css/images/clients/windowsphone.png' alt='Windows Phone' title='Windows Phone' />";
-        }
-        if (clientLowered == "dlna") {
-
-            return "<img src='css/images/clients/dlna.png' alt='Dlna' title='Dlna' />";
-        }
-
-        return connection.Client;
-    },
-
-    getNowPlayingImage: function (item) {
-
-        if (item) {
-
-            if (item.BackdropImageTag) {
-                var url = ApiClient.getImageUrl(item.Id, {
-                    type: "Backdrop",
-                    height: 100,
-                    tag: item.BackdropImageTag
-                });
-
-                return "<img class='clientNowPlayingImage' src='" + url + "' alt='" + item.Name + "' title='" + item.Name + "' />";
-            }
-            else if (item.PrimaryImageTag) {
-
-                var url = ApiClient.getImageUrl(item.Id, {
-                    type: "Primary",
-                    height: 100,
-                    tag: item.PrimaryImageTag
-                });
-
-                return "<img class='clientNowPlayingImage' src='" + url + "' alt='" + item.Name + "' title='" + item.Name + "' />";
-            }
-        }
-
-        return "";
-    },
-
-    getNowPlayingText: function (connection, item) {
-
-        var html = "";
-
-        if (item) {
-
-            html += "<div>" + item.Name + "</div>";
-
-            html += "<div>";
-
-            if (item.RunTimeTicks) {
-                html += DashboardPage.getDisplayText(connection.NowPlayingPositionTicks || 0) + " / ";
-
-                html += DashboardPage.getDisplayText(item.RunTimeTicks);
-            }
-
-            html += "</div>";
-        }
-
-        return html;
-    },
-
-    getDisplayText: function (ticks) {
-
-        var ticksPerHour = 36000000000;
-
-        var parts = [];
-
-        var hours = ticks / ticksPerHour;
-        hours = parseInt(hours);
-
-        if (hours) {
-            parts.push(hours);
-        }
-
-        ticks -= (hours * ticksPerHour);
-
-        var ticksPerMinute = 600000000;
-
-        var minutes = ticks / ticksPerMinute;
-        minutes = parseInt(minutes);
-
-        ticks -= (minutes * ticksPerMinute);
-
-        if (minutes < 10) {
-            minutes = '0' + minutes;
-        }
-        parts.push(minutes);
-
-        var ticksPerSecond = 10000000;
-
-        var seconds = ticks / ticksPerSecond;
-        seconds = parseInt(seconds);
-
-        if (seconds < 10) {
-            seconds = '0' + seconds;
-        }
-        parts.push(seconds);
-
-        return parts.join(':');
-    },
-
-    renderRunningTasks: function (dashboardInfo) {
-
-        var page = $.mobile.activePage;
-
-        var html = '';
-
-        if (!dashboardInfo.RunningTasks.length) {
-            html += '<p>No tasks are currently running.</p>';
-        }
-
-        for (var i = 0, length = dashboardInfo.RunningTasks.length; i < length; i++) {
-
-
-            var task = dashboardInfo.RunningTasks[i];
-
-            html += '<p>';
-
-            html += task.Name;
-
-            if (task.State == "Running") {
-                var progress = Math.round(task.CurrentProgressPercentage || 0);
-                html += '<span style="color:#267F00;margin-right:5px;font-weight:bold;"> - ' + progress + '%</span>';
-
-                html += '<button type="button" data-icon="stop" data-iconpos="notext" data-inline="true" data-theme="b" data-mini="true" onclick="DashboardPage.stopTask(\'' + task.Id + '\');">Stop</button>';
-            }
-            else if (task.State == "Cancelling") {
-                html += '<span style="color:#cc0000;"> - Stopping</span>';
-            }
-
-            html += '</p>';
-        }
-
-
-        $('#divRunningTasks', page).html(html).trigger('create');
-    },
-
-    renderSystemInfo: function (dashboardInfo) {
-
-        Dashboard.updateSystemInfo(dashboardInfo.SystemInfo);
-
-        var page = $.mobile.activePage;
-
-        $('#appVersionNumber', page).html(dashboardInfo.SystemInfo.Version);
-
-        if (dashboardInfo.RunningTasks.filter(function (task) {
-
-            return task.Id == dashboardInfo.ApplicationUpdateTaskId;
-
-        }).length) {
-
-            $('#btnUpdateApplication', page).button('disable');
-        } else {
-            $('#btnUpdateApplication', page).button('enable');
-        }
-
-        DashboardPage.renderApplicationUpdateInfo(dashboardInfo);
-        DashboardPage.renderPluginUpdateInfo(dashboardInfo);
-        DashboardPage.renderPendingInstallations(dashboardInfo.SystemInfo);
-    },
-
-    renderApplicationUpdateInfo: function (dashboardInfo) {
-
-        var page = $.mobile.activePage;
-
-        if (dashboardInfo.SystemInfo.IsNetworkDeployed && !dashboardInfo.SystemInfo.HasPendingRestart) {
-
-            // Only check once every 10 mins
-            if (DashboardPage.lastAppUpdateCheck && (new Date().getTime() - DashboardPage.lastAppUpdateCheck) < 600000) {
-                return;
-            }
-
-            DashboardPage.lastAppUpdateCheck = new Date().getTime();
-
-            ApiClient.getAvailableApplicationUpdate().done(function (packageInfo) {
-
-                var version = packageInfo[0];
-
-                if (!version) {
-                    $('#pUpToDate', page).show();
-                    $('#pUpdateNow', page).hide();
-                } else {
-                    $('#pUpToDate', page).hide();
-
-                    $('#pUpdateNow', page).show();
-
-                    $('#newVersionNumber', page).html("Version " + version.versionStr + " is now available for download.");
-                }
-
-            }).fail(function () {
-
-                Dashboard.showFooterNotification({ html: '<img src="css/images/notifications/error.png" class="notificationIcon" />There was an error connecting to the remote Media Browser repository.', id: "MB3ConnectionError" });
-
-            });
-
-        } else {
-
-            if (dashboardInfo.SystemInfo.HasPendingRestart) {
-                $('#pUpToDate', page).hide();
-            } else {
-                $('#pUpToDate', page).show();
-            }
-
-            $('#pUpdateNow', page).hide();
-        }
-    },
-
-    renderPendingInstallations: function (systemInfo) {
-
-        var page = $.mobile.activePage;
-
-        if (systemInfo.CompletedInstallations.length) {
-
-            $('#collapsiblePendingInstallations', page).show();
-
-        } else {
-            $('#collapsiblePendingInstallations', page).hide();
-
-            return;
-        }
-
-        var html = '';
-
-        for (var i = 0, length = systemInfo.CompletedInstallations.length; i < length; i++) {
-
-            var update = systemInfo.CompletedInstallations[i];
-
-            html += '<div><strong>' + update.Name + '</strong> (' + update.Version + ')</div>';
-        }
-
-        $('#pendingInstallations', page).html(html);
-    },
-
-    renderPluginUpdateInfo: function (dashboardInfo) {
-
-        // Only check once every 10 mins
-        if (DashboardPage.lastPluginUpdateCheck && (new Date().getTime() - DashboardPage.lastPluginUpdateCheck) < 600000) {
-            return;
-        }
-
-        DashboardPage.lastPluginUpdateCheck = new Date().getTime();
-
-        var page = $.mobile.activePage;
-
-        ApiClient.getAvailablePluginUpdates().done(function (updates) {
-
-            var elem = $('#pPluginUpdates', page);
-
-            if (updates.length) {
-
-                elem.show();
-
-            } else {
-                elem.hide();
-
-                return;
-            }
-            var html = '';
-
-            for (var i = 0, length = updates.length; i < length; i++) {
-
-                var update = updates[i];
-
-                html += '<p><strong>A new version of ' + update.name + ' is available!</strong></p>';
-
-                html += '<button type="button" data-icon="download" data-theme="b" onclick="DashboardPage.installPluginUpdate(this);" data-name="' + update.name + '" data-version="' + update.versionStr + '" data-classification="' + update.classification + '">Update Now</button>';
-            }
-
-            elem.html(html).trigger('create');
-
-        }).fail(function () {
-
-            Dashboard.showFooterNotification({ html: '<img src="css/images/notifications/error.png" class="notificationIcon" />There was an error connecting to the remote Media Browser repository.', id: "MB3ConnectionError" });
-
-        });
-    },
-
-    installPluginUpdate: function (button) {
-
-        $(button).button('disable');
-
-        var name = button.getAttribute('data-name');
-        var version = button.getAttribute('data-version');
-        var classification = button.getAttribute('data-classification');
-
-        Dashboard.showLoadingMsg();
-
-        ApiClient.installPlugin(name, classification, version).done(function () {
-
-            Dashboard.hideLoadingMsg();
-        });
-    },
-
-    updateApplication: function () {
-
-        var page = $.mobile.activePage;
-        $('#btnUpdateApplication', page).button('disable');
-
-        Dashboard.showLoadingMsg();
-
-        ApiClient.startScheduledTask(DashboardPage.lastDashboardInfo.ApplicationUpdateTaskId).done(function () {
-
-            DashboardPage.pollForInfo();
-
-            Dashboard.hideLoadingMsg();
-        });
-    },
-
-    stopTask: function (id) {
-
-        ApiClient.stopScheduledTask(id).done(function () {
-
-            DashboardPage.pollForInfo();
-        });
-
-    }
-};
-
-$(document).on('pageshow', "#dashboardPage", DashboardPage.onPageShow).on('pagehide', "#dashboardPage", DashboardPage.onPageHide);

+ 0 - 46
MediaBrowser.WebDashboard/Html/scripts/DisplaySettingsPage.js

@@ -1,46 +0,0 @@
-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);

+ 0 - 175
MediaBrowser.WebDashboard/Html/scripts/EditUserPage.js

@@ -1,175 +0,0 @@
-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);

+ 0 - 506
MediaBrowser.WebDashboard/Html/scripts/Extensions.js

@@ -1,506 +0,0 @@
-// 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);
-};
-
-/**
-*
-*  Secure Hash Algorithm (SHA1)
-*  http://www.webtoolkit.info/
-*
-**/
-
-function SHA1(msg) {
-
-    function rotate_left(n, s) {
-        var t4 = (n << s) | (n >>> (32 - s));
-        return t4;
-    };
-
-    function lsb_hex(val) {
-        var str = "";
-        var i;
-        var vh;
-        var vl;
-
-        for (i = 0; i <= 6; i += 2) {
-            vh = (val >>> (i * 4 + 4)) & 0x0f;
-            vl = (val >>> (i * 4)) & 0x0f;
-            str += vh.toString(16) + vl.toString(16);
-        }
-        return str;
-    };
-
-    function cvt_hex(val) {
-        var str = "";
-        var i;
-        var v;
-
-        for (i = 7; i >= 0; i--) {
-            v = (val >>> (i * 4)) & 0x0f;
-            str += v.toString(16);
-        }
-        return str;
-    };
-
-
-    function Utf8Encode(string) {
-        string = string.replace(/\r\n/g, "\n");
-        var utftext = "";
-
-        for (var n = 0; n < string.length; n++) {
-
-            var c = string.charCodeAt(n);
-
-            if (c < 128) {
-                utftext += String.fromCharCode(c);
-            }
-            else if ((c > 127) && (c < 2048)) {
-                utftext += String.fromCharCode((c >> 6) | 192);
-                utftext += String.fromCharCode((c & 63) | 128);
-            }
-            else {
-                utftext += String.fromCharCode((c >> 12) | 224);
-                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
-                utftext += String.fromCharCode((c & 63) | 128);
-            }
-
-        }
-
-        return utftext;
-    };
-
-    var blockstart;
-    var i, j;
-    var W = new Array(80);
-    var H0 = 0x67452301;
-    var H1 = 0xEFCDAB89;
-    var H2 = 0x98BADCFE;
-    var H3 = 0x10325476;
-    var H4 = 0xC3D2E1F0;
-    var A, B, C, D, E;
-    var temp;
-
-    msg = Utf8Encode(msg);
-
-    var msg_len = msg.length;
-
-    var word_array = new Array();
-    for (i = 0; i < msg_len - 3; i += 4) {
-        j = msg.charCodeAt(i) << 24 | msg.charCodeAt(i + 1) << 16 |
-		msg.charCodeAt(i + 2) << 8 | msg.charCodeAt(i + 3);
-        word_array.push(j);
-    }
-
-    switch (msg_len % 4) {
-        case 0:
-            i = 0x080000000;
-            break;
-        case 1:
-            i = msg.charCodeAt(msg_len - 1) << 24 | 0x0800000;
-            break;
-
-        case 2:
-            i = msg.charCodeAt(msg_len - 2) << 24 | msg.charCodeAt(msg_len - 1) << 16 | 0x08000;
-            break;
-
-        case 3:
-            i = msg.charCodeAt(msg_len - 3) << 24 | msg.charCodeAt(msg_len - 2) << 16 | msg.charCodeAt(msg_len - 1) << 8 | 0x80;
-            break;
-    }
-
-    word_array.push(i);
-
-    while ((word_array.length % 16) != 14) word_array.push(0);
-
-    word_array.push(msg_len >>> 29);
-    word_array.push((msg_len << 3) & 0x0ffffffff);
-
-
-    for (blockstart = 0; blockstart < word_array.length; blockstart += 16) {
-
-        for (i = 0; i < 16; i++) W[i] = word_array[blockstart + i];
-        for (i = 16; i <= 79; i++) W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
-
-        A = H0;
-        B = H1;
-        C = H2;
-        D = H3;
-        E = H4;
-
-        for (i = 0; i <= 19; i++) {
-            temp = (rotate_left(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
-            E = D;
-            D = C;
-            C = rotate_left(B, 30);
-            B = A;
-            A = temp;
-        }
-
-        for (i = 20; i <= 39; i++) {
-            temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
-            E = D;
-            D = C;
-            C = rotate_left(B, 30);
-            B = A;
-            A = temp;
-        }
-
-        for (i = 40; i <= 59; i++) {
-            temp = (rotate_left(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
-            E = D;
-            D = C;
-            C = rotate_left(B, 30);
-            B = A;
-            A = temp;
-        }
-
-        for (i = 60; i <= 79; i++) {
-            temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff;
-            E = D;
-            D = C;
-            C = rotate_left(B, 30);
-            B = A;
-            A = temp;
-        }
-
-        H0 = (H0 + A) & 0x0ffffffff;
-        H1 = (H1 + B) & 0x0ffffffff;
-        H2 = (H2 + C) & 0x0ffffffff;
-        H3 = (H3 + D) & 0x0ffffffff;
-        H4 = (H4 + E) & 0x0ffffffff;
-
-    }
-
-    var temp = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4);
-
-    return temp.toLowerCase();
-
-}
-
-// jqm.page.params.js - version 0.1
-// Copyright (c) 2011, Kin Blas
-// All rights reserved.
-//
-// 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);

+ 0 - 106
MediaBrowser.WebDashboard/Html/scripts/IndexPage.js

@@ -1,106 +0,0 @@
-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);

+ 0 - 376
MediaBrowser.WebDashboard/Html/scripts/ItemDetailPage.js

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

+ 0 - 46
MediaBrowser.WebDashboard/Html/scripts/ItemListPage.js

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

部分文件因为文件数量过多而无法显示