diff --git a/ApiClient.js b/ApiClient.js index 84f34e6814..2e11a72fca 100644 --- a/ApiClient.js +++ b/ApiClient.js @@ -839,6 +839,63 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) { return deferred.promise(); }; + self.uploadImage = function (itemId, imageType, file) { + + if (!itemId) { + throw new Error("null itemId"); + } + + if (!imageType) { + throw new Error("null imageType"); + } + + if (!file) { + throw new Error("File must be an image."); + } + + if (file.type != "image/png" && file.type != "image/jpeg" && file.type != "image/jpeg") { + throw new Error("File must be an image."); + } + + var deferred = $.Deferred(); + + var reader = new FileReader(); + + reader.onerror = function () { + deferred.reject(); + }; + + reader.onabort = function () { + deferred.reject(); + }; + + // Closure to capture the file information. + reader.onload = function (e) { + + var data = window.btoa(e.target.result); + + var url = self.getUrl("Items/" + itemId + "/Images/" + imageType); + + self.ajax({ + type: "POST", + url: url, + data: data, + contentType: "image/" + file.name.substring(file.name.lastIndexOf('.') + 1) + }).done(function (result) { + + deferred.resolveWith(null, [result]); + + }).fail(function () { + deferred.reject(); + }); + }; + + // Read in the image file as a data URL. + reader.readAsBinaryString(file); + + return deferred.promise(); + }; + /** * Gets the list of installed plugins on the server */ diff --git a/dashboard-ui/edititemimages.html b/dashboard-ui/edititemimages.html new file mode 100644 index 0000000000..11d3489083 --- /dev/null +++ b/dashboard-ui/edititemimages.html @@ -0,0 +1,57 @@ + + + + Media Browser + + +
+
+ +
+

+

+

+
+ Images +
+ +
+

Add/Update Image

+
+

JPG/PNG only.

+ + +
+

Drop Image Here

+ +
+ +
+
+
+
+ + +
+ + diff --git a/dashboard-ui/itemdetails.html b/dashboard-ui/itemdetails.html index fc1ccf37e8..9ca7ada0c9 100644 --- a/dashboard-ui/itemdetails.html +++ b/dashboard-ui/itemdetails.html @@ -97,10 +97,12 @@
- - +
+ + +
diff --git a/dashboard-ui/scripts/Itemdetailpage.js b/dashboard-ui/scripts/Itemdetailpage.js index 0df187f62d..2a377b16ea 100644 --- a/dashboard-ui/scripts/Itemdetailpage.js +++ b/dashboard-ui/scripts/Itemdetailpage.js @@ -14,69 +14,18 @@ renderHeader(page, item); - var name = item.Name; - - if (item.IndexNumber != null) { - name = item.IndexNumber + " - " + name; - } - if (item.ParentIndexNumber != null && item.Type != "Episode") { - name = item.ParentIndexNumber + "." + name; - } - $('#itemImage', page).html(LibraryBrowser.getDetailImageHtml(item)); - - Dashboard.setPageTitle(name); - - $('#itemName', page).html(name); - - if (item.AlbumArtist && item.Type == "Audio") { - $('#grandParentName', page).html('' + item.AlbumArtist + '').show().trigger('create'); - } - else if (item.AlbumArtist && item.Type == "MusicAlbum") { - $('#grandParentName', page).html('' + item.AlbumArtist + '').show().trigger('create'); - } - else if (item.SeriesName && item.Type == "Episode") { - - $('#grandParentName', page).html('' + item.SeriesName + '').show().trigger('create'); - } - else { - $('#grandParentName', page).hide(); - } - - if (item.SeriesName && item.Type == "Season") { - - $('#parentName', page).html('' + item.SeriesName + '').show().trigger('create'); - } - else if (item.ParentIndexNumber && item.Type == "Episode") { - - $('#parentName', page).html('Season ' + item.ParentIndexNumber + '').show().trigger('create'); - } - else if (item.Album && item.Type == "Audio" && item.ParentId) { - $('#parentName', page).html('' + item.Album + '').show().trigger('create'); - - } - else if (item.AlbumArtist && item.Type == "MusicAlbum") { - $('#grandParentName', page).html('' + item.AlbumArtist + '').show().trigger('create'); - - } - else if (item.Album) { - $('#parentName', page).html(item.Album).show(); - - } - else { - $('#parentName', page).hide(); - } + + LibraryBrowser.renderTitle(item, $('#itemName', page), $('#parentName', page), $('#grandParentName', page)); var context = getContext(item); setInitialCollapsibleState(page, item, context); renderDetails(page, item, context); if (MediaPlayer.canPlay(item)) { - $('#btnPlay', page).show(); - $('#playButtonShadow', page).show(); + $('#playButtonContainer', page).show(); } else { - $('#btnPlay', page).hide(); - $('#playButtonShadow', page).hide(); + $('#playButtonContainer', page).hide(); } $(".autoNumeric").autoNumeric('init'); @@ -256,7 +205,7 @@ } else { $('#itemPremiereDate', page).hide(); } - + LibraryBrowser.renderBudget($('#itemBudget', page), item); LibraryBrowser.renderRevenue($('#itemRevenue', page), item); @@ -285,7 +234,7 @@ } else { var shape = "smallPoster"; - + if (item.Type == "Season") { shape = "smallBackdrop"; } @@ -572,6 +521,11 @@ LibraryBrowser.showPlayMenu(this, currentItem.Id, currentItem.MediaType, userdata.PlaybackPositionTicks); }); + $('#btnEdit', page).on('click', function () { + + Dashboard.navigate("edititemimages.html?id=" + currentItem.Id); + }); + }).on('pageshow', "#itemDetailPage", function () { var page = this; diff --git a/dashboard-ui/scripts/edititemimages.js b/dashboard-ui/scripts/edititemimages.js new file mode 100644 index 0000000000..e0df6a73c2 --- /dev/null +++ b/dashboard-ui/scripts/edititemimages.js @@ -0,0 +1,159 @@ +(function ($, document, window, FileReader, escape) { + + var currentItem; + var currentFile; + + function reload(page) { + + var id = getParameterByName('id'); + + Dashboard.showLoadingMsg(); + + ApiClient.getItem(Dashboard.getCurrentUserId(), id).done(function (item) { + + currentItem = item; + + LibraryBrowser.renderTitle(item, $('#itemName', page), $('#parentName', page), $('#grandParentName', page)); + + Dashboard.hideLoadingMsg(); + }); + } + + function onFileReaderError(evt) { + + Dashboard.hideLoadingMsg(); + + switch (evt.target.error.code) { + case evt.target.error.NOT_FOUND_ERR: + Dashboard.showError('File Not Found!'); + break; + case evt.target.error.NOT_READABLE_ERR: + Dashboard.showError('File is not readable'); + break; + case evt.target.error.ABORT_ERR: + break; // noop + default: + Dashboard.showError('An error occurred reading this file.'); + }; + } + + function setFiles(page, files) { + + var file = files[0]; + + if (!file || !file.type.match('image.*')) { + $('#imageOutput', page).html(''); + $('#fldUpload', page).hide(); + currentFile = null; + return; + } + + currentFile = file; + + var reader = new FileReader(); + + reader.onerror = onFileReaderError; + reader.onloadstart = function () { + $('#fldUpload', page).hide(); + }; + reader.onabort = function () { + Dashboard.hideLoadingMsg(); + Dashboard.showError('File read cancelled'); + }; + + // Closure to capture the file information. + reader.onload = (function (theFile) { + return function (e) { + + // Render thumbnail. + var html = [''].join(''); + + $('#imageOutput', page).html(html); + $('#fldUpload', page).show(); + }; + })(file); + + // Read in the image file as a data URL. + reader.readAsDataURL(file); + } + + function processImageChangeResult(page) { + + Dashboard.hideLoadingMsg(); + + Dashboard.validateCurrentUser(page); + reload(page); + } + + function editItemImages() { + + var self = this; + + self.onSubmit = function () { + + var file = currentFile; + + if (!file) { + return false; + } + + if (file.type != "image/png" && file.type != "image/jpeg" && file.type != "image/jpeg") { + return false; + } + + Dashboard.showLoadingMsg(); + + var page = $.mobile.activePage; + + var imageType = $('#selectImageType', page).val(); + + ApiClient.uploadImage(currentItem.Id, imageType, file).done(function () { + + processImageChangeResult(page); + + }); + + return false; + }; + } + + window.EditItemImagesPage = new editItemImages(); + + $(document).on('pageinit', "#editItemImagesPage", function () { + + var page = this; + + + }).on('pageshow', "#editItemImagesPage", function () { + + var page = this; + + reload(page); + + $("#imageDropZone", page).on('dragover', function (e) { + + e.preventDefault(); + + e.originalEvent.dataTransfer.dropEffect = 'Copy'; + + return false; + + }).on('drop', function (e) { + + e.preventDefault(); + + setFiles(page, e.originalEvent.dataTransfer.files); + + return false; + }); + + }).on('pagehide', "#editItemImagesPage", function () { + + var page = this; + + currentItem = null; + + $("#imageDropZone", page).off('dragover').off('drop'); + }); + +})(jQuery, document, window, FileReader, escape); \ No newline at end of file diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index e62d226f99..66b8f96c37 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -630,6 +630,60 @@ }, + renderTitle: function (item, nameElem, parentNameElem, grandParentNameElem) { + + var name = item.Name; + + if (item.IndexNumber != null) { + name = item.IndexNumber + " - " + name; + } + if (item.ParentIndexNumber != null && item.Type != "Episode") { + name = item.ParentIndexNumber + "." + name; + } + + Dashboard.setPageTitle(name); + + nameElem.html(name); + + if (item.AlbumArtist && item.Type == "Audio") { + grandParentNameElem.html('' + item.AlbumArtist + '').show().trigger('create'); + } + else if (item.AlbumArtist && item.Type == "MusicAlbum") { + grandParentNameElem.html('' + item.AlbumArtist + '').show().trigger('create'); + } + else if (item.SeriesName && item.Type == "Episode") { + + grandParentNameElem.html('' + item.SeriesName + '').show().trigger('create'); + } + else { + grandParentNameElem.hide(); + } + + if (item.SeriesName && item.Type == "Season") { + + parentNameElem.html('' + item.SeriesName + '').show().trigger('create'); + } + else if (item.ParentIndexNumber && item.Type == "Episode") { + + parentNameElem.html('Season ' + item.ParentIndexNumber + '').show().trigger('create'); + } + else if (item.Album && item.Type == "Audio" && item.ParentId) { + parentNameElem.html('' + item.Album + '').show().trigger('create'); + + } + else if (item.AlbumArtist && item.Type == "MusicAlbum") { + grandParentNameElem.html('' + item.AlbumArtist + '').show().trigger('create'); + + } + else if (item.Album) { + parentNameElem.html(item.Album).show(); + + } + else { + parentNameElem.hide(); + } + }, + renderLinks: function (linksElem, item) { var links = []; diff --git a/dashboard-ui/scripts/userimagepage.js b/dashboard-ui/scripts/userimagepage.js index d5b04eea59..ee07c82a93 100644 --- a/dashboard-ui/scripts/userimagepage.js +++ b/dashboard-ui/scripts/userimagepage.js @@ -76,9 +76,7 @@ Dashboard.showError('File read cancelled'); } - function setFiles(files) { - - var page = $.mobile.activePage; + function setFiles(page, files) { var file = files[0]; @@ -117,7 +115,7 @@ e.preventDefault(); - setFiles(e.originalEvent.dataTransfer.files); + setFiles($.mobile.activePage, e.originalEvent.dataTransfer.files); return false; } @@ -174,7 +172,7 @@ self.onFileUploadChange = function (fileUpload) { - setFiles(fileUpload.files); + setFiles($.mobile.activePage, fileUpload.files); }; } diff --git a/packages.config b/packages.config index e8ca33ab5f..23ebca2930 100644 --- a/packages.config +++ b/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file