switch to shared image editor

This commit is contained in:
Luke Pulverenti 2016-08-30 02:06:24 -04:00
parent 228cefadd8
commit 4c97201a3c
15 changed files with 264 additions and 174 deletions

View file

@ -14,12 +14,12 @@
},
"devDependencies": {},
"ignore": [],
"version": "1.4.200",
"_release": "1.4.200",
"version": "1.4.203",
"_release": "1.4.203",
"_resolution": {
"type": "version",
"tag": "1.4.200",
"commit": "37218220cf08f35c9a86ca1a59bd945351ae6cb4"
"tag": "1.4.203",
"commit": "0970763d22302d071ef6ff77e0fc565f69ef2982"
},
"_source": "https://github.com/MediaBrowser/emby-webcomponents.git",
"_target": "^1.2.1",

View file

@ -327,6 +327,10 @@
width: 50%;
}
.midBackdropCard-scalable {
width: 50%;
}
.squareCard-scalable {
width: 50%;
}
@ -354,6 +358,10 @@
.backdropCard-scalable {
width: 50%;
}
.midBackdropCard-scalable {
width: 50%;
}
}
@media all and (min-width: 500px) {
@ -384,6 +392,10 @@
.overflowSquareCard-scalable {
width: 30%;
}
.midBackdropCard-scalable {
width: 33.333333333333333333333333333333%;
}
}
@media all and (min-width: 700px) {
@ -419,6 +431,10 @@
.squareCard-scalable {
width: 20%;
}
.midBackdropCard-scalable {
width: 25%;
}
}
@media all and (min-width: 1000px) {
@ -462,6 +478,10 @@
.smallBackdropCard-scalable {
width: 16.666666666666666666666666666667%;
}
.midBackdropCard-scalable {
width: 20%;
}
}

View file

@ -0,0 +1,379 @@
define(['dialogHelper', 'connectionManager', 'loading', 'dom', 'layoutManager', 'globalize', 'scrollHelper', 'require', 'cardStyle', 'formDialogStyle', 'emby-button', 'paper-icon-button-light'], function (dialogHelper, connectionManager, loading, dom, layoutManager, globalize, scrollHelper, require) {
var currentItem;
var hasChanges = false;
function getBaseRemoteOptions() {
var options = {};
options.itemId = currentItem.Id;
return options;
}
function reload(page, item) {
loading.show();
var apiClient;
if (item) {
apiClient = connectionManager.getApiClient(item.ServerId);
reloadItem(page, item, apiClient);
}
else {
apiClient = connectionManager.getApiClient(currentItem.ServerId);
apiClient.getItem(apiClient.getCurrentUserId(), currentItem.Id).then(function (item) {
reloadItem(page, item, apiClient);
});
}
}
function addListeners(elems, eventName, fn) {
for (var i = 0, length = elems.length; i < length; i++) {
elems[i].addEventListener(eventName, fn);
}
}
function reloadItem(page, item, apiClient) {
currentItem = item;
apiClient.getRemoteImageProviders(getBaseRemoteOptions()).then(function (providers) {
var btnBrowseAllImages = page.querySelectorAll('.btnBrowseAllImages');
for (var i = 0, length = btnBrowseAllImages.length; i < length; i++) {
if (providers.length) {
btnBrowseAllImages[i].classList.remove('hide');
} else {
btnBrowseAllImages[i].classList.add('hide');
}
}
apiClient.getItemImageInfos(currentItem.Id).then(function (imageInfos) {
renderStandardImages(page, apiClient, item, imageInfos, providers);
renderBackdrops(page, apiClient, item, imageInfos, providers);
renderScreenshots(page, apiClient, item, imageInfos, providers);
loading.hide();
});
});
}
function getImageUrl(item, apiClient, type, index, options) {
options = options || {};
options.type = type;
options.index = index;
if (type == 'Backdrop') {
options.tag = item.BackdropImageTags[index];
} else if (type == 'Screenshot') {
options.tag = item.ScreenshotImageTags[index];
} else if (type == 'Primary') {
options.tag = item.PrimaryImageTag || item.ImageTags[type];
} else {
options.tag = item.ImageTags[type];
}
// For search hints
return apiClient.getScaledImageUrl(item.Id || item.ItemId, options);
}
function getCardHtml(image, index, apiClient, imageProviders, imageSize, tagName, enableFooterButtons) {
var html = '';
var cssClass = "card scalableCard";
cssClass += " midBackdropCard midBackdropCard-scalable";
if (tagName == 'button') {
html += '<button type="button" class="' + cssClass + '">';
} else {
html += '<div class="' + cssClass + '">';
}
html += '<div class="cardBox visualCardBox">';
html += '<div class="cardScalable visualCardBox-cardScalable" style="background-color:transparent;">';
html += '<div class="cardPadder-backdrop"></div>';
html += '<div class="cardContent">';
var imageUrl = getImageUrl(currentItem, apiClient, image.ImageType, image.ImageIndex, { maxWidth: imageSize });
html += '<div class="cardImageContainer" style="background-image:url(\'' + imageUrl + '\');background-position:center bottom;"></div>';
html += '</div>';
html += '</div>';
html += '<div class="cardFooter visualCardBox-cardFooter">';
html += '<h3 class="cardText cardTextCentered" style="margin:0;">' + image.ImageType + '</h3>';
html += '<div class="cardText cardText-secondary cardTextCentered">';
if (image.Width && image.Height) {
html += image.Width + ' X ' + image.Height;
} else {
html += '&nbsp;';
}
html += '</div>';
if (enableFooterButtons) {
html += '<div class="cardText cardTextCentered">';
if (image.ImageType == "Backdrop" || image.ImageType == "Screenshot") {
if (index > 0) {
html += '<button is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex - 1) + '" title="' + globalize.translate('sharedcomponents#MoveLeft') + '"><i class="md-icon">chevron_left</i></button>';
} else {
html += '<button is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('sharedcomponents#MoveLeft') + '"><i class="md-icon">chevron_left</i></button>';
}
if (index < length - 1) {
html += '<button is="paper-icon-button-light" class="btnMoveImage autoSize" data-imagetype="' + image.ImageType + '" data-index="' + image.ImageIndex + '" data-newindex="' + (image.ImageIndex + 1) + '" title="' + globalize.translate('sharedcomponents#MoveRight') + '"><i class="md-icon">chevron_right</i></button>';
} else {
html += '<button is="paper-icon-button-light" class="autoSize" disabled title="' + globalize.translate('sharedcomponents#MoveRight') + '"><i class="md-icon">chevron_right</i></button>';
}
}
else {
if (imageProviders.length) {
html += '<button is="paper-icon-button-light" data-imagetype="' + image.ImageType + '" class="btnSearchImages autoSize" title="' + globalize.translate('sharedcomponents#Search') + '"><i class="md-icon">search</i></button>';
}
}
html += '<button is="paper-icon-button-light" data-imagetype="' + image.ImageType + '" data-index="' + (image.ImageIndex != null ? image.ImageIndex : "null") + '" class="btnDeleteImage autoSize" title="' + globalize.translate('sharedcomponents#Delete') + '"><i class="md-icon">delete</i></button>';
html += '</div>';
}
html += '</div>';
html += '</div>';
html += '</div>';
html += '</' + tagName + '>';
return html;
}
function renderImages(page, item, apiClient, images, imageProviders, elem) {
var html = '';
var imageSize = 300;
var windowSize = dom.getWindowSize();
if (windowSize.innerWidth >= 1280) {
imageSize = Math.round(windowSize.innerWidth / 4);
}
var tagName = layoutManager.tv ? 'button' : 'div';
var enableFooterButtons = !layoutManager.tv;
for (var i = 0, length = images.length; i < length; i++) {
var image = images[i];
html += getCardHtml(image, i, apiClient, imageProviders, imageSize, tagName, enableFooterButtons);
}
elem.innerHTML = html;
ImageLoader.lazyChildren(elem);
addListeners(elem.querySelectorAll('.btnSearchImages'), 'click', function () {
showImageDownloader(page, this.getAttribute('data-imagetype'));
});
addListeners(elem.querySelectorAll('.btnDeleteImage'), 'click', function () {
var type = this.getAttribute('data-imagetype');
var index = this.getAttribute('data-index');
index = index == "null" ? null : parseInt(index);
require(['confirm'], function (confirm) {
confirm(globalize.translate('sharedcomponents#ConfirmDeleteImage')).then(function () {
ApiClient.deleteItemImage(currentItem.Id, type, index).then(function () {
hasChanges = true;
reload(page);
});
});
});
});
addListeners(elem.querySelectorAll('.btnMoveImage'), 'click', function () {
var type = this.getAttribute('data-imagetype');
var index = parseInt(this.getAttribute('data-index'));
var newIndex = parseInt(this.getAttribute('data-newindex'));
ApiClient.updateItemImageIndex(currentItem.Id, type, index, newIndex).then(function () {
hasChanges = true;
reload(page);
});
});
}
function renderStandardImages(page, apiClient, item, imageInfos, imageProviders) {
var images = imageInfos.filter(function (i) {
return i.ImageType != "Screenshot" && i.ImageType != "Backdrop" && i.ImageType != "Chapter";
});
renderImages(page, item, apiClient, images, imageProviders, page.querySelector('#images'));
}
function renderBackdrops(page, apiClient, item, imageInfos, imageProviders) {
var images = imageInfos.filter(function (i) {
return i.ImageType == "Backdrop";
}).sort(function (a, b) {
return a.ImageIndex - b.ImageIndex;
});
if (images.length) {
page.querySelector('#backdropsContainer', page).classList.remove('hide');
renderImages(page, item, apiClient, images, imageProviders, page.querySelector('#backdrops'));
} else {
page.querySelector('#backdropsContainer', page).classList.add('hide');
}
}
function renderScreenshots(page, apiClient, item, imageInfos, imageProviders) {
var images = imageInfos.filter(function (i) {
return i.ImageType == "Screenshot";
}).sort(function (a, b) {
return a.ImageIndex - b.ImageIndex;
});
if (images.length) {
page.querySelector('#screenshotsContainer', page).classList.remove('hide');
renderImages(page, item, apiClient, images, imageProviders, page.querySelector('#screenshots'));
} else {
page.querySelector('#screenshotsContainer', page).classList.add('hide');
}
}
function showImageDownloader(page, imageType) {
require(['components/imagedownloader/imagedownloader'], function (ImageDownloader) {
ImageDownloader.show(currentItem.Id, currentItem.Type, imageType).then(function () {
hasChanges = true;
reload(page);
});
});
}
function initEditor(page, options) {
addListeners(page.querySelectorAll('.btnOpenUploadMenu'), 'click', function () {
var imageType = this.getAttribute('data-imagetype');
require(['components/imageuploader/imageuploader'], function (imageUploader) {
imageUploader.show(currentItem.Id, {
theme: options.theme,
imageType: imageType
}).then(function (hasChanged) {
if (hasChanged) {
hasChanges = true;
reload(page);
}
});
});
});
addListeners(page.querySelectorAll('.btnBrowseAllImages'), 'click', function () {
showImageDownloader(page, this.getAttribute('data-imagetype') || 'Primary');
});
}
function showEditor(options, resolve, reject) {
var itemId = options.itemId;
var serverId = options.serverId;
loading.show();
require(['text!./imageeditor.template.html'], function (template) {
var apiClient = connectionManager.getApiClient(serverId);
apiClient.getItem(apiClient.getCurrentUserId(), itemId).then(function (item) {
var dialogOptions = {
removeOnClose: true
};
if (layoutManager.tv) {
dialogOptions.size = 'fullscreen';
} else {
dialogOptions.size = 'fullscreen-border';
}
var dlg = dialogHelper.createDialog(dialogOptions);
dlg.classList.add('formDialog');
dlg.innerHTML = globalize.translateDocument(template, 'sharedcomponents');
dlg.querySelector('.formDialogHeaderTitle').innerHTML = item.Name;
document.body.appendChild(dlg);
if (layoutManager.tv) {
scrollHelper.centerFocus.on(dlg, false);
}
initEditor(dlg, options);
// Has to be assigned a z-index after the call to .open()
dlg.addEventListener('close', function () {
if (layoutManager.tv) {
scrollHelper.centerFocus.off(dlg, false);
}
loading.hide();
if (hasChanges) {
resolve();
} else {
reject();
}
});
dialogHelper.open(dlg);
reload(dlg, item);
dlg.querySelector('.btnCancel').addEventListener('click', function () {
dialogHelper.close(dlg);
});
});
});
}
return {
show: function (options) {
return new Promise(function (resolve, reject) {
hasChanges = false;
showEditor(options, resolve, reject);
});
}
};
});

View file

@ -0,0 +1,55 @@
<div class="formDialogHeader">
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="md-icon">&#xE5C4;</i></button>
<div class="formDialogHeaderTitle">
</div>
</div>
<div class="formDialogContent">
<div class="dialogContentInner">
<div id="imagesContainer">
<div style="display: flex; align-items: center;margin:2em 0 .5em;">
<h1 style="margin:0;">${Images}</h1>
<button type="button" is="emby-button" class="btnBrowseAllImages fab mini autoSize" style="margin-left: 1em;">
<i class="md-icon">search</i>
</button>
<button type="button" is="emby-button" class="btnOpenUploadMenu fab mini autoSize" style="margin-left: .5em;">
<i class="md-icon">add</i>
</button>
</div>
<div id="images" class="itemsContainer vertical-wrap">
</div>
<br />
</div>
<div id="backdropsContainer" class="hide">
<div style="display: flex; align-items: center;margin:1em 0 .5em;">
<h1 style="margin:0;">${Backdrops}</h1>
<button type="button" is="emby-button" class="btnBrowseAllImages fab mini autoSize" style="margin-left: 1em;" data-imagetype="Backdrop">
<i class="md-icon">search</i>
</button>
<button type="button" is="emby-button" class="btnOpenUploadMenu fab mini autoSize" style="margin-left: .5em;" data-imagetype="Backdrop">
<i class="md-icon">add</i>
</button>
</div>
<div id="backdrops" class="itemsContainer vertical-wrap">
</div>
<br />
</div>
<div id="screenshotsContainer" class="hide">
<div style="display: flex; align-items: center; margin: 1em 0 .5em;">
<h1 style="margin: 0;">${Screenshots}</h1>
<button type="button" is="emby-button" class="btnBrowseAllImages fab mini autoSize" style="margin-left: 1em;" data-imagetype="Screenshot">
<i class="md-icon">search</i>
</button>
<button type="button" is="emby-button" class="btnOpenUploadMenu fab mini autoSize" style="margin-left: .5em;" data-imagetype="Screenshot">
<i class="md-icon">add</i>
</button>
</div>
<div id="screenshots" class="itemsContainer vertical-wrap">
</div>
</div>
</div>
</div>

View file

@ -58,13 +58,11 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
if (itemHelper.canEditImages(user, item.Type)) {
if (isMobileApp) {
if (options.editImages !== false) {
commands.push({
name: globalize.translate('sharedcomponents#EditImages'),
id: 'editimages'
});
}
if (options.editImages !== false) {
commands.push({
name: globalize.translate('sharedcomponents#EditImages'),
id: 'editimages'
});
}
}
@ -318,9 +316,13 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
}
case 'editimages':
{
require(['components/imageeditor/imageeditor'], function (ImageEditor) {
require(['imageEditor'], function (imageEditor) {
ImageEditor.show(itemId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
imageEditor.show({
itemId: itemId,
serverId: serverId
}).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
});
break;
}

View file

@ -174,21 +174,25 @@
var html = '';
var cssClass = "card scalableCard";
var padderClass;
if (currentItemType == "Episode") {
cssClass += " backdropCard backdropCard-scalable";
padderClass = 'cardPadder-backdrop';
}
else if (currentItemType == "MusicAlbum" || currentItemType == "MusicArtist") {
cssClass += " squareCard squareCard-scalable";
padderClass = 'cardPadder-square';
}
else {
cssClass += " portraitCard portraitCard-scalable";
padderClass = 'cardPadder-portrait';
}
html += '<button type="button" class="' + cssClass + '" data-index="' + index + '">';
html += '<div class="cardBox visualCardBox">';
html += '<div class="cardScalable visualCardBox-cardScalable">';
html += '<div class="cardPadder-portrait"></div>';
html += '<div class="' + padderClass + '"></div>';
html += '<div class="cardContent searchImage">';

View file

@ -271,5 +271,9 @@
"AutomaticallySyncNewContentHelp": "New content added to this folder will be automatically synced to the device.",
"LabelItemLimit": "Item limit:",
"LabelItemLimitHelp": "Optional. Set a limit to the number of items that will be synced.",
"PleaseSelectDeviceToSyncTo": "Please select a device to sync to."
"PleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
"Screenshots": "Screenshots",
"MoveRight": "Move right",
"MoveLeft": "Move left",
"ConfirmDeleteImage": "Delete image?"
}