mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2024-11-18 03:18:19 -07:00
#551 - Add manual image selection for movies
This commit is contained in:
parent
fd2f6fa1b3
commit
2515b6d9ae
18
ApiClient.js
18
ApiClient.js
@ -306,16 +306,20 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getAvailableRemoteImages = function (itemId, imageType) {
|
self.getAvailableRemoteImages = function (options) {
|
||||||
|
|
||||||
if (!itemId) {
|
if (!options) {
|
||||||
throw new Error("null itemId");
|
throw new Error("null options");
|
||||||
}
|
|
||||||
if (!imageType) {
|
|
||||||
throw new Error("null imageType");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = self.getUrl("Items/" + itemId + "/RemoteImages/" + imageType);
|
var urlPrefix = "Items/" + options.itemId;
|
||||||
|
|
||||||
|
var imageType = options.imageType;
|
||||||
|
|
||||||
|
delete options.itemId;
|
||||||
|
delete options.imageType;
|
||||||
|
|
||||||
|
var url = self.getUrl(urlPrefix + "/RemoteImages/" + imageType, options);
|
||||||
|
|
||||||
return self.ajax({
|
return self.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
|
@ -26,8 +26,54 @@
|
|||||||
top: -2px;
|
top: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
overflow-y: auto;
|
||||||
|
width: 300px;
|
||||||
|
height: 500px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remoteImageContainer {
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
margin: 5px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remoteImageDetails {
|
||||||
|
background: #eee;
|
||||||
|
padding: 3px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remoteImage {
|
||||||
|
background-position: center bottom;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remotePosterImage {
|
||||||
|
width: 150px;
|
||||||
|
height: 225px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remoteBackdropImage {
|
||||||
|
width: 272px;
|
||||||
|
height: 153px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 500px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media all and (min-width: 600px) {
|
@media all and (min-width: 600px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
.editPageSidebar {
|
.editPageSidebar {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 36px;
|
top: 36px;
|
||||||
@ -44,3 +90,110 @@
|
|||||||
width: 70%;
|
width: 70%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media all and (min-width: 700px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 600px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 800px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 700px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 900px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 800px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 1000px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 900px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 1100px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 1000px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 1200px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 1100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 1300px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 1200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 1400px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 1300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 1500px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 1400px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 1600px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 1500px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 1700px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 1600px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 1800px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 1700px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-width: 1900px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
width: 1800px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-height: 800px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
height: 600px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media all and (min-height: 900px) {
|
||||||
|
|
||||||
|
.availableImagesList {
|
||||||
|
height: 700px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="margin: -25px 0 1em;">
|
<div style="margin: -25px 0 1em;">
|
||||||
<a href="#popupUpload" data-rel="popup" data-role="button" data-inline="true" data-icon="plus" data-mini="true" data-transition="pop">Upload Image</a>
|
<a id="lnkBrowseImages" href="#popupDownload" data-rel="popup" data-position-to="window" data-role="button" data-inline="true" data-icon="plus" data-mini="true" data-transition="pop">Browse Images</a>
|
||||||
|
<a href="#popupUpload" data-rel="popup" data-position-to="window" data-role="button" data-inline="true" data-icon="plus" data-mini="true" data-transition="pop">Upload Image</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="imagesContainer" style="display: none;">
|
<div id="imagesContainer" style="display: none;">
|
||||||
@ -53,7 +54,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-role="popup" id="popupUpload" class="ui-corner-all" data-theme="c">
|
<div data-role="popup" id="popupUpload" data-theme="c" data-corners="false">
|
||||||
<form id="uploadItemImageForm" style="max-width: 100%; margin: 0 1.5em 1.5em;">
|
<form id="uploadItemImageForm" style="max-width: 100%; margin: 0 1.5em 1.5em;">
|
||||||
<h2>Add/Update Image</h2>
|
<h2>Add/Update Image</h2>
|
||||||
<div>
|
<div>
|
||||||
@ -88,6 +89,44 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div data-role="popup" id="popupDownload" class="popup" data-corners="false">
|
||||||
|
|
||||||
|
<a href="#" data-rel="back" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close</a>
|
||||||
|
<div class="ui-bar-a" style="text-align: center; padding: 0 20px;">
|
||||||
|
<h3 style="margin: .5em 0;">Browse Images</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-role="content" class="ui-content" style="padding: 5px 15px;">
|
||||||
|
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<div style="margin: 0; display: inline-block;">
|
||||||
|
<label for="selectBrowsableImageType">Image type:</label>
|
||||||
|
</div>
|
||||||
|
<div style="margin: 0; display: inline-block;">
|
||||||
|
<select id="selectBrowsableImageType" name="selectBrowsableImageType" data-mini="true" data-inline="true">
|
||||||
|
<option value="Primary">Primary</option>
|
||||||
|
<option value="Art">Art</option>
|
||||||
|
<option value="Backdrop">Backdrop</option>
|
||||||
|
<option value="Banner">Banner</option>
|
||||||
|
<option value="Box">Box</option>
|
||||||
|
<option value="BoxRear">Box rear</option>
|
||||||
|
<option value="Disc">Disc</option>
|
||||||
|
<option value="Logo">Logo</option>
|
||||||
|
<option value="Menu">Menu</option>
|
||||||
|
<option value="Screenshot">Screenshot</option>
|
||||||
|
<option value="Thumb">Thumb</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="availableImagesPaging" style="margin: 0; display: inline-block;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="availableImagesList"></div>
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<a href="#" data-rel="back" data-role="button" data-mini="true" data-inline="true" data-icon="delete">Close</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$('#uploadItemImageForm').on('submit', EditItemImagesPage.onSubmit);
|
$('#uploadItemImageForm').on('submit', EditItemImagesPage.onSubmit);
|
||||||
</script>
|
</script>
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
var currentItem;
|
var currentItem;
|
||||||
var currentFile;
|
var currentFile;
|
||||||
|
|
||||||
|
var browsableImagePageSize = 10;
|
||||||
|
var browsableImageStartIndex = 0;
|
||||||
|
var browsableImageType = 'Primary';
|
||||||
|
|
||||||
function updateTabs(page, item) {
|
function updateTabs(page, item) {
|
||||||
|
|
||||||
var query = MetadataEditor.getEditQueryString(item);
|
var query = MetadataEditor.getEditQueryString(item);
|
||||||
@ -11,6 +15,152 @@
|
|||||||
$('#btnEditMetadata', page).attr('href', 'edititemmetadata.html?' + query);
|
$('#btnEditMetadata', page).attr('href', 'edititemmetadata.html?' + query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reloadBrowsableImages(page) {
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
itemId: currentItem.Id,
|
||||||
|
imageType: browsableImageType,
|
||||||
|
startIndex: browsableImageStartIndex,
|
||||||
|
limit: browsableImagePageSize
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiClient.getAvailableRemoteImages(options).done(function (result) {
|
||||||
|
|
||||||
|
renderRemoteImages(page, currentItem, result, browsableImageType, options.startIndex, options.limit);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderRemoteImages(page, item, imagesResult, imageType, startIndex, limit) {
|
||||||
|
|
||||||
|
$('.availableImagesPaging', page).html(getPagingHtml(startIndex, limit, imagesResult.TotalRecordCount)).trigger('create');
|
||||||
|
|
||||||
|
var html = '';
|
||||||
|
|
||||||
|
for (var i = 0, length = imagesResult.Images.length; i < length; i++) {
|
||||||
|
|
||||||
|
html += getRemoteImageHtml(imagesResult.Images[i], imageType);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.availableImagesList', page).html(html).trigger('create');
|
||||||
|
|
||||||
|
$('.selectPage', page).on('change', function () {
|
||||||
|
browsableImageStartIndex = (parseInt(this.value) - 1) * browsableImagePageSize;
|
||||||
|
reloadBrowsableImages(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btnNextPage', page).on('click', function () {
|
||||||
|
browsableImageStartIndex += browsableImagePageSize;
|
||||||
|
reloadBrowsableImages(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btnPreviousPage', page).on('click', function () {
|
||||||
|
browsableImageStartIndex -= browsableImagePageSize;
|
||||||
|
reloadBrowsableImages(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getRemoteImageHtml(image, imageType) {
|
||||||
|
|
||||||
|
var html = '';
|
||||||
|
|
||||||
|
html += '<div class="remoteImageContainer">';
|
||||||
|
|
||||||
|
var cssClass = "remoteImage";
|
||||||
|
|
||||||
|
if (imageType == "Backdrop") {
|
||||||
|
cssClass += " remoteBackdropImage";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cssClass += " remotePosterImage";
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '<div class="' + cssClass + '" style="background-image:url(\'' + image.Url + '\');">';
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
html += '<div class="remoteImageDetails">';
|
||||||
|
html += image.ProviderName;
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
if (image.Width || image.Height) {
|
||||||
|
|
||||||
|
html += '<div class="remoteImageDetails">';
|
||||||
|
html += image.Width + 'x' + image.Height;
|
||||||
|
|
||||||
|
if (image.Language) {
|
||||||
|
|
||||||
|
html += ' • ' + image.Language;
|
||||||
|
}
|
||||||
|
html += '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image.CommunityRating) {
|
||||||
|
html += '<div class="remoteImageDetails">';
|
||||||
|
html += image.CommunityRating.toFixed(1);
|
||||||
|
|
||||||
|
if (image.VoteCount) {
|
||||||
|
html += ' • ' + image.VoteCount + ' votes';
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '<div><button type="button" data-icon="save" data-mini="true">Download</button></div>';
|
||||||
|
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPagingHtml(startIndex, limit, totalRecordCount) {
|
||||||
|
|
||||||
|
var html = '';
|
||||||
|
|
||||||
|
var pageCount = Math.ceil(totalRecordCount / limit);
|
||||||
|
var pageNumber = (startIndex / limit) + 1;
|
||||||
|
|
||||||
|
var dropdownHtml = '<select class="selectPage" data-enhance="false" data-role="none">';
|
||||||
|
for (var i = 1; i <= pageCount; i++) {
|
||||||
|
|
||||||
|
if (i == pageNumber) {
|
||||||
|
dropdownHtml += '<option value="' + i + '" selected="selected">' + i + '</option>';
|
||||||
|
} else {
|
||||||
|
dropdownHtml += '<option value="' + i + '">' + i + '</option>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dropdownHtml += '</select>';
|
||||||
|
|
||||||
|
var recordsEnd = Math.min(startIndex + limit, totalRecordCount);
|
||||||
|
|
||||||
|
// 20 is the minimum page size
|
||||||
|
var showControls = totalRecordCount > 20;
|
||||||
|
|
||||||
|
html += '<div class="listPaging">';
|
||||||
|
|
||||||
|
html += '<span style="margin-right: 10px;">';
|
||||||
|
|
||||||
|
var startAtDisplay = totalRecordCount ? startIndex + 1 : 0;
|
||||||
|
html += startAtDisplay + '-' + recordsEnd + ' of ' + totalRecordCount;
|
||||||
|
|
||||||
|
if (showControls) {
|
||||||
|
html += ', page ' + dropdownHtml + ' of ' + pageCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '</span>';
|
||||||
|
|
||||||
|
if (showControls) {
|
||||||
|
html += '<button data-icon="arrow-left" data-iconpos="notext" data-inline="true" data-mini="true" class="btnPreviousPage" ' + (startIndex ? '' : 'disabled') + '>Previous Page</button>';
|
||||||
|
|
||||||
|
html += '<button data-icon="arrow-right" data-iconpos="notext" data-inline="true" data-mini="true" class="btnNextPage" ' + (startIndex + limit > totalRecordCount ? 'disabled' : '') + '>Next Page</button>';
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
function reload(page) {
|
function reload(page) {
|
||||||
|
|
||||||
Dashboard.showLoadingMsg();
|
Dashboard.showLoadingMsg();
|
||||||
@ -273,7 +423,7 @@
|
|||||||
$('.libraryTree', page).on('itemclicked', function (event, data) {
|
$('.libraryTree', page).on('itemclicked', function (event, data) {
|
||||||
|
|
||||||
if (data.id != currentItem.Id) {
|
if (data.id != currentItem.Id) {
|
||||||
|
|
||||||
MetadataEditor.currentItemId = data.id;
|
MetadataEditor.currentItemId = data.id;
|
||||||
MetadataEditor.currentItemName = data.itemName;
|
MetadataEditor.currentItemName = data.itemName;
|
||||||
MetadataEditor.currentItemType = data.itemType;
|
MetadataEditor.currentItemType = data.itemType;
|
||||||
@ -286,6 +436,19 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#lnkBrowseImages', page).on('click', function () {
|
||||||
|
|
||||||
|
reloadBrowsableImages(page);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#selectBrowsableImageType', page).on('change', function () {
|
||||||
|
|
||||||
|
browsableImageType = this.value;
|
||||||
|
browsableImageStartIndex = 0;
|
||||||
|
|
||||||
|
reloadBrowsableImages(page);
|
||||||
|
});
|
||||||
|
|
||||||
}).on('pageshow', "#editItemImagesPage", function () {
|
}).on('pageshow', "#editItemImagesPage", function () {
|
||||||
|
|
||||||
var page = this;
|
var page = this;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.183" targetFramework="net45" />
|
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.184" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Common" version="3.9.62" targetFramework="net45" />
|
<package id="ServiceStack.Common" version="3.9.62" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
|
<package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
Loading…
Reference in New Issue
Block a user