diff --git a/ApiClient.js b/ApiClient.js index 2e11a72fca..ae97e86f11 100644 --- a/ApiClient.js +++ b/ApiClient.js @@ -758,7 +758,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { * @param {String} userId * @param {String} imageType The type of image to delete, based on the server-side ImageType enum. */ - self.deleteUserImage = function (userId, imageType) { + self.deleteUserImage = function (userId, imageType, imageIndex) { if (!userId) { throw new Error("null userId"); @@ -770,12 +770,71 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { var url = self.getUrl("Users/" + userId + "/Images/" + imageType); + if (imageIndex != null) { + url += "/" + imageIndex; + } + return self.ajax({ type: "DELETE", url: url }); }; + self.deleteItemImage = function (itemId, imageType, imageIndex) { + + if (!itemId) { + throw new Error("null itemId"); + } + + if (!imageType) { + throw new Error("null imageType"); + } + + var url = self.getUrl("Items/" + itemId + "/Images/" + imageType); + + if (imageIndex != null) { + url += "/" + imageIndex; + } + + return self.ajax({ + type: "DELETE", + url: url + }); + }; + + self.updateItemImageIndex = function (itemId, imageType, imageIndex, newIndex) { + + if (!itemId) { + throw new Error("null itemId"); + } + + if (!imageType) { + throw new Error("null imageType"); + } + + var url = self.getUrl("Items/" + itemId + "/Images/" + imageType + "/" + imageIndex + "/Index", { newIndex: newIndex }); + + return self.ajax({ + type: "POST", + url: url + }); + }; + + self.getItemImageInfos = function (itemId) { + + if (!itemId) { + throw new Error("null itemId"); + } + + var url = self.getUrl("Items/" + itemId + "/Images"); + + return self.ajax({ + type: "GET", + url: url, + dataType: "json" + }); + }; + /** * Uploads a user image * @param {String} userId @@ -839,7 +898,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { return deferred.promise(); }; - self.uploadImage = function (itemId, imageType, file) { + self.uploadItemImage = function (itemId, imageType, file) { if (!itemId) { throw new Error("null itemId"); diff --git a/dashboard-ui/css/librarybrowser.css b/dashboard-ui/css/librarybrowser.css index f1b17ec04d..a009c9f748 100644 --- a/dashboard-ui/css/librarybrowser.css +++ b/dashboard-ui/css/librarybrowser.css @@ -199,6 +199,10 @@ overflow: hidden; } +.itemMediaInfo { + font-size: 14px; +} + .mediaInfoStream { display: inline-block; vertical-align: top; @@ -212,13 +216,14 @@ } .mediaInfoDetails { - margin: 0 0 0 1.5em; + margin: 0 0 0 .25em; padding: 0; - list-style-type: circle; + list-style-type: none; } .mediaInfoLabel { color: #bbb; + margin-right: 3px; } .posterRibbon { diff --git a/dashboard-ui/edititemimages.html b/dashboard-ui/edititemimages.html index 11d3489083..ecbad83485 100644 --- a/dashboard-ui/edititemimages.html +++ b/dashboard-ui/edititemimages.html @@ -11,43 +11,72 @@

+
+ Metadata Images
-
-

Add/Update Image

-
-

JPG/PNG only.

- +
+ Upload Image +
-
-

Drop Image Here

- -
- + + + + + +
+ +
+
+

Add/Update Image

+
+

JPG/PNG only.

+ + +
+

Drop Image Here

+ +
+ + Cancel +
+
+
+ diff --git a/dashboard-ui/itemdetails.html b/dashboard-ui/itemdetails.html index 9ca7ada0c9..a167e7f492 100644 --- a/dashboard-ui/itemdetails.html +++ b/dashboard-ui/itemdetails.html @@ -101,7 +101,9 @@ - +
@@ -139,7 +141,7 @@
diff --git a/dashboard-ui/itemlist.html b/dashboard-ui/itemlist.html index 72a55b3c5a..2d92a21f9f 100644 --- a/dashboard-ui/itemlist.html +++ b/dashboard-ui/itemlist.html @@ -7,7 +7,11 @@
-

+

+ +

diff --git a/dashboard-ui/scripts/Itemdetailpage.js b/dashboard-ui/scripts/Itemdetailpage.js index 2a377b16ea..996581b2a2 100644 --- a/dashboard-ui/scripts/Itemdetailpage.js +++ b/dashboard-ui/scripts/Itemdetailpage.js @@ -15,7 +15,7 @@ renderHeader(page, item); $('#itemImage', page).html(LibraryBrowser.getDetailImageHtml(item)); - + LibraryBrowser.renderTitle(item, $('#itemName', page), $('#parentName', page), $('#grandParentName', page)); var context = getContext(item); @@ -28,6 +28,16 @@ $('#playButtonContainer', page).hide(); } + Dashboard.getCurrentUser().done(function (user) { + + if (user.Configuration.IsAdministrator) { + $('#editButtonContainer', page).show(); + } else { + $('#editButtonContainer', page).hide(); + } + + }); + $(".autoNumeric").autoNumeric('init'); Dashboard.hideLoadingMsg(); @@ -367,57 +377,65 @@ html += '
    '; if (stream.Codec) { - html += '
  • Codec ' + stream.Codec + '
  • '; + html += '
  • Codec: ' + stream.Codec + '
  • '; } if (stream.Profile) { - html += '
  • Profile ' + stream.Profile + '
  • '; + html += '
  • Profile: ' + stream.Profile + '
  • '; } if (stream.Level) { - html += '
  • Level ' + stream.Level + '
  • '; + html += '
  • Level: ' + stream.Level + '
  • '; } if (stream.Language) { - html += '
  • Language ' + stream.Language + '
  • '; + html += '
  • Language: ' + stream.Language + '
  • '; } if (stream.Width) { - html += '
  • Width ' + stream.Width + '
  • '; + html += '
  • Width: ' + stream.Width + '
  • '; } if (stream.Height) { - html += '
  • Height ' + stream.Height + '
  • '; + html += '
  • Height: ' + stream.Height + '
  • '; } if (stream.AspectRatio) { - html += '
  • Aspect Ratio ' + stream.AspectRatio + '
  • '; + html += '
  • Aspect Ratio: ' + stream.AspectRatio + '
  • '; } if (stream.BitRate) { - html += '
  • Bitrate ' + stream.BitRate + '
  • '; + html += '
  • Bitrate: ' + stream.BitRate + '
  • '; } if (stream.Channels) { - html += '
  • Channels ' + stream.Channels + '
  • '; + html += '
  • Channels: ' + stream.Channels + '
  • '; } if (stream.SampleRate) { - html += '
  • Sample Rate ' + stream.SampleRate + '
  • '; + html += '
  • Sample Rate: ' + stream.SampleRate + '
  • '; } var framerate = stream.AverageFrameRate || stream.RealFrameRate; if (framerate) { - html += '
  • Framerate ' + framerate + '
  • '; + html += '
  • Framerate: ' + framerate + '
  • '; } if (stream.PixelFormat) { - html += '
  • Pixel Format ' + stream.PixelFormat + '
  • '; + html += '
  • Pixel Format: ' + stream.PixelFormat + '
  • '; } - if (stream.IsDefault) { - html += '
  • Default
  • '; - } - if (stream.IsForced) { - html += '
  • Forced
  • '; - } - if (stream.IsExternal) { - html += '
  • External
  • '; + if (stream.IsDefault || stream.IsForced || stream.IsExternal) { + + var vals = []; + + if (stream.IsDefault) { + vals.push("Default"); + } + if (stream.IsForced) { + vals.push("Forced"); + } + if (stream.IsExternal) { + vals.push("External"); + } + + html += '
  • Flags: ' + vals.join(", ") + '
  • '; } + if (stream.Path) { - html += '
  • Path ' + stream.Path + '
  • '; + html += '
  • Path: ' + stream.Path + '
  • '; } html += '
'; diff --git a/dashboard-ui/scripts/edititemimages.js b/dashboard-ui/scripts/edititemimages.js index e0df6a73c2..7773fac39d 100644 --- a/dashboard-ui/scripts/edititemimages.js +++ b/dashboard-ui/scripts/edititemimages.js @@ -13,12 +13,113 @@ currentItem = item; - LibraryBrowser.renderTitle(item, $('#itemName', page), $('#parentName', page), $('#grandParentName', page)); + LibraryBrowser.renderTitle(item, $('#itemName', page), $('#parentName', page), $('#grandParentName', page), true); - Dashboard.hideLoadingMsg(); + ApiClient.getItemImageInfos(currentItem.Id).done(function (imageInfos) { + renderStandardImages(page, item, imageInfos); + renderBackdrops(page, item, imageInfos); + renderScreenshots(page, item, imageInfos); + Dashboard.hideLoadingMsg(); + }); }); } + function renderImages(page, item, images, elem) { + + var html = ''; + + for (var i = 0, length = images.length; i < length; i++) { + + var image = images[i]; + + html += '
'; + + html += '
'; + + html += '
'; + html += '

' + image.ImageType + '

'; + + html += '

' + image.Width + ' * ' + image.Height + '

'; + + html += '

' + (parseInt(image.Size / 1024)) + ' KB

'; + + html += '

'; + + if (image.ImageType == "Backdrop" || image.ImageType == "Screenshot") { + + if (i > 0) { + html += ''; + } else { + html += ''; + } + + if (i < length - 1) { + html += ''; + } else { + html += ''; + } + } + + html += ''; + + html += '

'; + + html += '
'; + + html += '
'; + } + + elem.html(html).trigger('create'); + } + + function renderStandardImages(page, item, imageInfos) { + + var images = imageInfos.filter(function (i) { + return i.ImageType != "Screenshot" && i.ImageType != "Backdrop" && i.ImageType != "Chapter"; + }); + + if (images.length) { + $('#imagesContainer', page).show(); + renderImages(page, item, images, $('#images', page)); + } else { + $('#imagesContainer', page).hide(); + } + } + + function renderBackdrops(page, item, imageInfos) { + + var images = imageInfos.filter(function (i) { + return i.ImageType == "Backdrop"; + + }).sort(function (a, b) { + return a.ImageIndex - b.ImageIndex; + }); + + if (images.length) { + $('#backdropsContainer', page).show(); + renderImages(page, item, images, $('#backdrops', page)); + } else { + $('#backdropsContainer', page).hide(); + } + } + + function renderScreenshots(page, item, imageInfos) { + + var images = imageInfos.filter(function (i) { + return i.ImageType == "Screenshot"; + + }).sort(function (a, b) { + return a.ImageIndex - b.ImageIndex; + }); + + if (images.length) { + $('#screenshotsContainer', page).show(); + renderImages(page, item, images, $('#screenshots', page)); + } else { + $('#screenshotsContainer', page).hide(); + } + } + function onFileReaderError(evt) { Dashboard.hideLoadingMsg(); @@ -79,9 +180,6 @@ function processImageChangeResult(page) { - Dashboard.hideLoadingMsg(); - - Dashboard.validateCurrentUser(page); reload(page); } @@ -107,14 +205,48 @@ var imageType = $('#selectImageType', page).val(); - ApiClient.uploadImage(currentItem.Id, imageType, file).done(function () { + ApiClient.uploadItemImage(currentItem.Id, imageType, file).done(function () { + $('#uploadImage', page).val('').trigger('change'); + $('#popupUpload', page).popup("close"); processImageChangeResult(page); }); return false; }; + + self.deleteImage = function (type, index) { + + var page = $.mobile.activePage; + + Dashboard.confirm("Are you sure you wish to delete this image?", "Delete " + type + " Image", function (result) { + + if (result) { + ApiClient.deleteItemImage(currentItem.Id, type, index).done(function () { + + processImageChangeResult(page); + + }); + } + + }); + + + }; + + self.moveImage = function (type, index, newIndex) { + + var page = $.mobile.activePage; + + ApiClient.updateItemImageIndex(currentItem.Id, type, index, newIndex).done(function () { + + processImageChangeResult(page); + + }); + + + }; } window.EditItemImagesPage = new editItemImages(); @@ -130,6 +262,10 @@ reload(page); + $('#uploadImage', page).on("change", function () { + setFiles(page, this.files); + }); + $("#imageDropZone", page).on('dragover', function (e) { e.preventDefault(); @@ -153,6 +289,8 @@ currentItem = null; + $('#uploadImage', page).off("change"); + $("#imageDropZone", page).off('dragover').off('drop'); }); diff --git a/dashboard-ui/scripts/itemlistpage.js b/dashboard-ui/scripts/itemlistpage.js index 5e0e38b13a..1a7b6537fc 100644 --- a/dashboard-ui/scripts/itemlistpage.js +++ b/dashboard-ui/scripts/itemlistpage.js @@ -78,6 +78,16 @@ $('#itemName', page).html(name); Dashboard.setPageTitle(name); }); + + Dashboard.getCurrentUser().done(function (user) { + + if (user.Configuration.IsAdministrator) { + $('#editButtonContainer', page).show(); + } else { + $('#editButtonContainer', page).hide(); + } + + }); } $(document).on('pageinit', "#itemListPage", function () { @@ -120,6 +130,11 @@ reloadItems(page); }); + $('#btnEdit', page).on('click', function () { + + Dashboard.navigate("edititemimages.html?id=" + query.ParentId); + }); + }).on('pageshow', "#itemListPage", function () { query.ParentId = getParameterByName('parentId'); diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index 66b8f96c37..f051443fa9 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -616,10 +616,10 @@ getMetroColor: function (str) { if (str) { - var char = String(str.substr(0, 1).charCodeAt()); + var character = String(str.substr(0, 1).charCodeAt()); var sum = 0; - for (var i = 0; i < char.length; i++) { - sum += parseInt(char.charAt(i)); + for (var i = 0; i < character.length; i++) { + sum += parseInt(character.charAt(i)); } var index = String(sum).substr(-1); @@ -630,11 +630,11 @@ }, - renderTitle: function (item, nameElem, parentNameElem, grandParentNameElem) { - + renderTitle: function (item, nameElem, parentNameElem, grandParentNameElem, linkToElement) { + var name = item.Name; - if (item.IndexNumber != null) { + if (item.IndexNumber != null && item.Type !== "Season") { name = item.IndexNumber + " - " + name; } if (item.ParentIndexNumber != null && item.Type != "Episode") { @@ -643,7 +643,11 @@ Dashboard.setPageTitle(name); - nameElem.html(name); + if (linkToElement) { + nameElem.html('' + name + '').trigger('create'); + } else { + nameElem.html(name); + } if (item.AlbumArtist && item.Type == "Audio") { grandParentNameElem.html('' + item.AlbumArtist + '').show().trigger('create'); diff --git a/packages.config b/packages.config index 23ebca2930..34667ce4cc 100644 --- a/packages.config +++ b/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file