diff --git a/dashboard-ui/bower_components/emby-webcomponents/collectioneditor/collectioneditor.js b/dashboard-ui/bower_components/emby-webcomponents/collectioneditor/collectioneditor.js
new file mode 100644
index 000000000..d16a5b0fa
--- /dev/null
+++ b/dashboard-ui/bower_components/emby-webcomponents/collectioneditor/collectioneditor.js
@@ -0,0 +1,264 @@
+define(['dialogHelper', 'loading', 'connectionManager', 'embyRouter', 'globalize', 'paper-checkbox', 'paper-input', 'paper-icon-button-light', 'emby-select'], function (dialogHelper, loading, connectionManager, embyRouter, globalize) {
+
+ var currentServerId;
+
+ function parentWithClass(elem, className) {
+
+ while (!elem.classList || !elem.classList.contains(className)) {
+ elem = elem.parentNode;
+
+ if (!elem) {
+ return null;
+ }
+ }
+
+ return elem;
+ }
+
+ function onSubmit(e) {
+ loading.show();
+
+ var panel = parentWithClass(this, 'dialog');
+
+ var collectionId = panel.querySelector('#selectCollectionToAddTo').value;
+
+ var apiClient = connectionManager.getApiClient(currentServerId);
+
+ if (collectionId) {
+ addToCollection(apiClient, panel, collectionId);
+ } else {
+ createCollection(apiClient, panel);
+ }
+
+ e.preventDefault();
+ return false;
+ }
+
+ function createCollection(apiClient, dlg) {
+
+ var url = apiClient.getUrl("Collections", {
+
+ Name: dlg.querySelector('#txtNewCollectionName').value,
+ IsLocked: !dlg.querySelector('#chkEnableInternetMetadata').checked,
+ Ids: dlg.querySelector('.fldSelectedItemIds').value || ''
+
+ //ParentId: getParameterByName('parentId') || LibraryMenu.getTopParentId()
+
+ });
+
+ apiClient.ajax({
+ type: "POST",
+ url: url,
+ dataType: "json"
+
+ }).then(function (result) {
+
+ loading.hide();
+
+ var id = result.Id;
+
+ dialogHelper.close(dlg);
+ redirectToCollection(apiClient, id);
+
+ });
+ }
+
+ function redirectToCollection(apiClient, id) {
+
+ apiClient.getItem(apiClient.getCurrentUserId(), id).then(function (item) {
+
+ embyRouter.showItem(item);
+ });
+ }
+
+ function addToCollection(apiClient, dlg, id) {
+
+ var url = apiClient.getUrl("Collections/" + id + "/Items", {
+
+ Ids: dlg.querySelector('.fldSelectedItemIds').value || ''
+ });
+
+ apiClient.ajax({
+ type: "POST",
+ url: url
+
+ }).then(function () {
+
+ loading.hide();
+
+ dialogHelper.close(dlg);
+
+ require(['toast'], function (toast) {
+ toast(globalize.translate('MessageItemsAdded'));
+ });
+ });
+ }
+
+ function onDialogClosed() {
+
+ loading.hide();
+ }
+
+ function triggerChange(select) {
+ select.dispatchEvent(new CustomEvent('change', {}));
+ }
+
+ function populateCollections(panel) {
+
+ loading.show();
+
+ var select = panel.querySelector('#selectCollectionToAddTo');
+
+ panel.querySelector('.newCollectionInfo').classList.add('hide');
+
+ var options = {
+
+ Recursive: true,
+ IncludeItemTypes: "BoxSet",
+ SortBy: "SortName"
+ };
+
+ var apiClient = connectionManager.getApiClient(currentServerId);
+ apiClient.getItems(apiClient.getCurrentUserId(), options).then(function (result) {
+
+ var html = '';
+
+ html += '';
+
+ html += result.Items.map(function (i) {
+
+ return '';
+ });
+
+ select.innerHTML = html;
+ select.value = '';
+ triggerChange(select);
+
+ loading.hide();
+ });
+ }
+
+ function getEditorHtml() {
+
+ var html = '';
+
+ html += '
';
+
+ return html;
+ }
+
+ function initEditor(content, items) {
+
+ content.querySelector('#selectCollectionToAddTo').addEventListener('change', function () {
+ if (this.value) {
+ content.querySelector('.newCollectionInfo').classList.add('hide');
+ content.querySelector('#txtNewCollectionName').removeAttribute('required');
+ } else {
+ content.querySelector('.newCollectionInfo').classList.remove('hide');
+ content.querySelector('#txtNewCollectionName').setAttribute('required', 'required');
+ }
+ });
+
+ content.querySelector('.newCollectionForm').addEventListener('submit', onSubmit);
+
+ content.querySelector('.fldSelectedItemIds', content).value = items.join(',');
+
+ if (items.length) {
+ content.querySelector('.fldSelectCollection').classList.remove('hide');
+ populateCollections(content);
+ } else {
+ content.querySelector('.fldSelectCollection').classList.add('hide');
+
+ var selectCollectionToAddTo = content.querySelector('#selectCollectionToAddTo');
+ selectCollectionToAddTo.innerHTML = '';
+ selectCollectionToAddTo.value = '';
+ triggerChange(selectCollectionToAddTo);
+ }
+ }
+
+ function collectioneditor() {
+
+ var self = this;
+
+ self.show = function (options) {
+
+ var items = options.items || {};
+ currentServerId = options.serverId;
+
+ var dlg = dialogHelper.createDialog({
+ size: 'small',
+ removeOnClose: true
+ });
+
+ dlg.classList.add('ui-body-b');
+ dlg.classList.add('background-theme-b');
+
+ var html = '';
+ var title = items.length ? globalize.translate('HeaderAddToCollection') : globalize.translate('HeaderNewCollection');
+
+ html += '';
+
+ html += getEditorHtml();
+
+ dlg.innerHTML = html;
+ document.body.appendChild(dlg);
+
+ initEditor(dlg, items);
+
+ dlg.addEventListener('close', onDialogClosed);
+
+ dialogHelper.open(dlg);
+
+ dlg.querySelector('.btnCancel').addEventListener('click', function () {
+
+ dialogHelper.close(dlg);
+ });
+ };
+ }
+
+ return collectioneditor;
+});
\ No newline at end of file
diff --git a/dashboard-ui/bower_components/emby-webcomponents/emby-select/emby-select.css b/dashboard-ui/bower_components/emby-webcomponents/emby-select/emby-select.css
new file mode 100644
index 000000000..2b1993d4f
--- /dev/null
+++ b/dashboard-ui/bower_components/emby-webcomponents/emby-select/emby-select.css
@@ -0,0 +1,44 @@
+[is="emby-select"] {
+ display: block;
+ margin: 0;
+ margin-bottom: 0 !important;
+ background: none;
+ border: 1px solid rgb(221, 221, 221);
+ border-width: 0 0 1px 0;
+ /* Prefixed box-sizing rules necessary for older browsers */
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ /* Remove select styling */
+ /* Font size must the 16px or larger to prevent iOS page zoom on focus */
+ font-size: inherit;
+ /* General select styles: change as needed */
+ font-family: inherit;
+ font-weight: bold;
+ color: inherit;
+ padding: .6em .8em .3em 0;
+ cursor: pointer;
+ outline: none !important;
+}
+
+.selectLabel {
+ display: block;
+}
+
+.selectLabelFocus {
+ color: #52B54B;
+}
+
+.emby-select-selectionbar {
+ height: 2px;
+ transform: scale(.01);
+ transition: transform .2s ease-out;
+ position: relative;
+ top: -1px;
+ margin-bottom: .5em;
+}
+
+[is="emby-select"]:focus + .emby-select-selectionbar {
+ background-color: #52B54B;
+ transform: none;
+}
diff --git a/dashboard-ui/bower_components/emby-webcomponents/emby-select/emby-select.js b/dashboard-ui/bower_components/emby-webcomponents/emby-select/emby-select.js
new file mode 100644
index 000000000..4f41cb6e1
--- /dev/null
+++ b/dashboard-ui/bower_components/emby-webcomponents/emby-select/emby-select.js
@@ -0,0 +1,112 @@
+define(['layoutManager', 'browser', 'actionsheet', 'css!./emby-select'], function (layoutManager, browser, actionsheet) {
+
+ var EmbySelectPrototype = Object.create(HTMLSelectElement.prototype);
+
+ function enableNativeMenu() {
+
+ // Take advantage of the native input methods
+ if (browser.tv) {
+ return true;
+ }
+
+ if (layoutManager.tv) {
+ return false;
+ }
+
+ return true;
+ }
+
+ function showActionSheeet(select) {
+
+ actionsheet.show({
+ items: select.options,
+ positionTo: select
+
+ }).then(function (value) {
+ select.value = value;
+ });
+ }
+
+ function getLabel(select) {
+ var elem = select.previousSibling;
+ while (elem && elem.tagName != 'LABEL') {
+ elem = elem.previousSibling;
+ }
+ return elem;
+ }
+
+ function onFocus(e) {
+ var label = getLabel(this);
+ if (label) {
+ label.classList.add('selectLabelFocus');
+ }
+ }
+
+ function onBlur(e) {
+ var label = getLabel(this);
+ if (label) {
+ label.classList.remove('selectLabelFocus');
+ }
+ }
+
+ function onMouseDown(e) {
+
+ if (!enableNativeMenu()) {
+ e.preventDefault();
+ showActionSheeet(this);
+ }
+ }
+
+ function onKeyDown(e) {
+
+ switch (e.keyCode) {
+
+ case 13:
+ if (!enableNativeMenu()) {
+ e.preventDefault();
+ showActionSheeet(this);
+ }
+ return;
+ case 37:
+ case 38:
+ case 39:
+ case 40:
+ if (layoutManager.tv) {
+ e.preventDefault();
+ }
+ return;
+ default:
+ break;
+ }
+ }
+
+ EmbySelectPrototype.createdCallback = function () {
+
+ if (!this.id) {
+ this.id = 'select' + new Date().getTime();
+ }
+ this.addEventListener('mousedown', onMouseDown);
+ this.addEventListener('keydown', onKeyDown);
+ this.addEventListener('focus', onFocus);
+ this.addEventListener('keydown', onBlur);
+ };
+
+ EmbySelectPrototype.attachedCallback = function () {
+
+ var label = this.ownerDocument.createElement('label');
+ label.innerHTML = this.getAttribute('label') || '';
+ label.classList.add('selectLabel');
+ label.htmlFor = this.id;
+ this.parentNode.insertBefore(label, this);
+
+ var div = document.createElement('div');
+ div.classList.add('emby-select-selectionbar');
+ div.innerHTML = '';
+ this.parentNode.insertBefore(div, this.nextSibling);
+ };
+
+ document.registerElement('emby-select', {
+ prototype: EmbySelectPrototype,
+ extends: 'select'
+ });
+});
\ No newline at end of file
diff --git a/dashboard-ui/components/collectioneditor/collectioneditor.js b/dashboard-ui/components/collectioneditor/collectioneditor.js
deleted file mode 100644
index d82b2d984..000000000
--- a/dashboard-ui/components/collectioneditor/collectioneditor.js
+++ /dev/null
@@ -1,239 +0,0 @@
-define(['dialogHelper', 'jQuery', 'paper-checkbox', 'paper-input', 'paper-icon-button-light'], function (dialogHelper, $) {
-
- function onSubmit() {
- Dashboard.showLoadingMsg();
-
- var panel = $(this).parents('.dialog')[0];
-
- var collectionId = $('#selectCollectionToAddTo', panel).val();
-
- if (collectionId) {
- addToCollection(panel, collectionId);
- } else {
- createCollection(panel);
- }
-
- return false;
- }
-
- function createCollection(dlg) {
-
- var url = ApiClient.getUrl("Collections", {
-
- Name: $('#txtNewCollectionName', dlg).val(),
- IsLocked: !$('#chkEnableInternetMetadata', dlg).checked(),
- Ids: $('.fldSelectedItemIds', dlg).val() || ''
-
- //ParentId: getParameterByName('parentId') || LibraryMenu.getTopParentId()
-
- });
-
- ApiClient.ajax({
- type: "POST",
- url: url,
- dataType: "json"
-
- }).then(function (result) {
-
- Dashboard.hideLoadingMsg();
-
- var id = result.Id;
-
- dialogHelper.close(dlg);
- redirectToCollection(id);
-
- });
- }
-
- function redirectToCollection(id) {
-
- var context = getParameterByName('context');
-
- ApiClient.getItem(Dashboard.getCurrentUserId(), id).then(function (item) {
-
- Dashboard.navigate(LibraryBrowser.getHref(item, context));
-
- });
- }
-
- function addToCollection(dlg, id) {
-
- var url = ApiClient.getUrl("Collections/" + id + "/Items", {
-
- Ids: $('.fldSelectedItemIds', dlg).val() || ''
- });
-
- ApiClient.ajax({
- type: "POST",
- url: url
-
- }).then(function () {
-
- Dashboard.hideLoadingMsg();
-
- dialogHelper.close(dlg);
-
- require(['toast'], function (toast) {
- toast(Globalize.translate('MessageItemsAdded'));
- });
- });
- }
-
- function onDialogClosed() {
-
- $(this).remove();
- Dashboard.hideLoadingMsg();
- }
-
- function populateCollections(panel) {
-
- Dashboard.showLoadingMsg();
-
- var select = $('#selectCollectionToAddTo', panel);
-
- $('.newCollectionInfo', panel).hide();
-
- var options = {
-
- Recursive: true,
- IncludeItemTypes: "BoxSet",
- SortBy: "SortName"
- };
-
- ApiClient.getItems(Dashboard.getCurrentUserId(), options).then(function (result) {
-
- var html = '';
-
- html += '';
-
- html += result.Items.map(function (i) {
-
- return '';
- });
-
- select.html(html).val('').trigger('change');
-
- Dashboard.hideLoadingMsg();
- });
- }
-
- function getEditorHtml() {
-
- var html = '';
-
- html += '';
-
- return html;
- }
-
- function initEditor(content, items) {
-
- $('#selectCollectionToAddTo', content).on('change', function () {
-
- if (this.value) {
- $('.newCollectionInfo', content).hide();
- $('#txtNewCollectionName', content).removeAttr('required');
- } else {
- $('.newCollectionInfo', content).show();
- $('#txtNewCollectionName', content).attr('required', 'required');
- }
- });
-
- $('.newCollectionForm', content).off('submit', onSubmit).on('submit', onSubmit);
-
- $('.fldSelectedItemIds', content).val(items.join(','));
-
- if (items.length) {
- $('.fldSelectCollection', content).show();
- populateCollections(content);
- } else {
- $('.fldSelectCollection', content).hide();
- $('#selectCollectionToAddTo', content).html('').val('').trigger('change');
- }
- }
-
- function collectioneditor() {
-
- var self = this;
-
- self.show = function (items) {
-
- items = items || [];
-
- var dlg = dialogHelper.createDialog({
- size: 'small'
- });
-
- dlg.classList.add('ui-body-b');
- dlg.classList.add('background-theme-b');
-
- var html = '';
- var title = items.length ? Globalize.translate('HeaderAddToCollection') : Globalize.translate('HeaderNewCollection');
-
- html += '';
-
- html += getEditorHtml();
-
- dlg.innerHTML = html;
- document.body.appendChild(dlg);
-
- initEditor(dlg, items);
-
- $(dlg).on('close', onDialogClosed);
-
- dialogHelper.open(dlg);
-
- $('.btnCancel', dlg).on('click', function () {
-
- dialogHelper.close(dlg);
- });
- };
- }
-
- return collectioneditor;
-});
\ No newline at end of file
diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js
index 2a5616e31..21fffed15 100644
--- a/dashboard-ui/scripts/librarybrowser.js
+++ b/dashboard-ui/scripts/librarybrowser.js
@@ -929,9 +929,12 @@
});
break;
case 'addtocollection':
- require(['collectioneditor'], function (collectioneditor) {
+ require(['collectionEditor'], function (collectionEditor) {
- new collectioneditor().show([itemId]);
+ new collectionEditor().show({
+ items: [itemId],
+ serverId: serverId
+ });
});
break;
case 'playlist':
diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js
index 76b192d41..88d6865d5 100644
--- a/dashboard-ui/scripts/librarylist.js
+++ b/dashboard-ui/scripts/librarylist.js
@@ -494,9 +494,12 @@
switch (id) {
case 'addtocollection':
- require(['collectioneditor'], function (collectioneditor) {
+ require(['collectionEditor'], function (collectionEditor) {
- new collectioneditor().show([itemId]);
+ new collectionEditor().show({
+ items: [itemId],
+ serverId: serverId
+ });
});
break;
case 'playlist':
@@ -1232,9 +1235,11 @@
switch (id) {
case 'addtocollection':
- require(['collectioneditor'], function (collectioneditor) {
+ require(['collectionEditor'], function (collectionEditor) {
- new collectioneditor().show(items);
+ new collectionEditor().show({
+ items: items
+ });
});
hideSelections();
break;
diff --git a/dashboard-ui/scripts/moviecollections.js b/dashboard-ui/scripts/moviecollections.js
index 28c154314..6d5a284da 100644
--- a/dashboard-ui/scripts/moviecollections.js
+++ b/dashboard-ui/scripts/moviecollections.js
@@ -189,9 +189,13 @@
// The button is created dynamically
$('.btnNewCollection', tabContent).on('click', function () {
- require(['collectioneditor'], function (collectioneditor) {
+ require(['collectionEditor'], function (collectionEditor) {
- new collectioneditor().show();
+ var serverId = ApiClient.serverInfo().Id;
+ new collectionEditor().show({
+ items: [],
+ serverId: serverId
+ });
});
});
diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js
index e00bdadf1..9c6463b67 100644
--- a/dashboard-ui/scripts/site.js
+++ b/dashboard-ui/scripts/site.js
@@ -1709,7 +1709,6 @@ var AppInfo = {};
ironCardList: 'components/ironcardlist/ironcardlist',
scrollThreshold: 'components/scrollthreshold',
directorybrowser: 'components/directorybrowser/directorybrowser',
- collectioneditor: 'components/collectioneditor/collectioneditor',
playlisteditor: 'components/playlisteditor/playlisteditor',
medialibrarycreator: 'components/medialibrarycreator/medialibrarycreator',
medialibraryeditor: 'components/medialibraryeditor/medialibraryeditor',
@@ -1768,11 +1767,13 @@ var AppInfo = {};
define("libjass", [bowerPath + "/libjass/libjass", "css!" + bowerPath + "/libjass/libjass"], returnFirstDependency);
+ define("collectionEditor", [embyWebComponentsBowerPath + "/collectioneditor/collectioneditor"], returnFirstDependency);
define("recordingCreator", [embyWebComponentsBowerPath + "/recordingcreator/recordingcreator"], returnFirstDependency);
define("recordingEditor", [embyWebComponentsBowerPath + "/recordingcreator/recordingeditor"], returnFirstDependency);
define("mediaInfo", [embyWebComponentsBowerPath + "/mediainfo/mediainfo"], returnFirstDependency);
define("backdrop", [embyWebComponentsBowerPath + "/backdrop/backdrop"], returnFirstDependency);
define("fetchHelper", [embyWebComponentsBowerPath + "/fetchhelper"], returnFirstDependency);
+ define("emby-select", [embyWebComponentsBowerPath + "/emby-select/emby-select"], returnFirstDependency);
define("tvguide", [embyWebComponentsBowerPath + "/guide/guide", 'embyRouter'], returnFirstDependency);
diff --git a/dashboard-ui/thirdparty/paper-button-style.css b/dashboard-ui/thirdparty/paper-button-style.css
index 5c4609ba0..25d9978eb 100644
--- a/dashboard-ui/thirdparty/paper-button-style.css
+++ b/dashboard-ui/thirdparty/paper-button-style.css
@@ -432,7 +432,11 @@ paper-input label, paper-textarea label {
margin-bottom: .5em;
}
-.ui-body-b .paper-input-container-0 .input-content.paper-input-container label, .ui-body-b .paper-input-container-0 .input-content.paper-input-container .paper-input-label, .ui-body-b paper-textarea label, .ui-body-b .selectLabel, .ui-body-b .paperListLabel, .ui-body-b .fieldDescription {
+.ui-body-b .paper-input-container-0 .input-content.paper-input-container label, .ui-body-b .paper-input-container-0 .input-content.paper-input-container .paper-input-label, .ui-body-b paper-textarea label, .ui-body-b .paperListLabel, .ui-body-b .fieldDescription {
+ color: #ccc;
+}
+
+.ui-body-b .selectLabel:not(.selectLabelFocus) {
color: #ccc;
}