/* eslint-disable indent */ /** * Module for library options editor. * @module components/libraryoptionseditor/libraryoptionseditor */ import globalize from '../../scripts/globalize'; import dom from '../../scripts/dom'; import '../../elements/emby-checkbox/emby-checkbox'; import '../../elements/emby-select/emby-select'; import '../../elements/emby-input/emby-input'; function populateLanguages(parent) { return ApiClient.getCultures().then(languages => { populateLanguagesIntoSelect(parent.querySelector('#selectLanguage'), languages); populateLanguagesIntoList(parent.querySelector('.subtitleDownloadLanguages'), languages); }); } function populateLanguagesIntoSelect(select, languages) { let html = ''; html += ""; for (let i = 0; i < languages.length; i++) { const culture = languages[i]; html += ``; } select.innerHTML = html; } function populateLanguagesIntoList(element, languages) { let html = ''; for (let i = 0; i < languages.length; i++) { const culture = languages[i]; html += ``; } element.innerHTML = html; } function populateCountries(select) { return ApiClient.getCountries().then(allCountries => { let html = ''; html += ""; for (let i = 0; i < allCountries.length; i++) { const culture = allCountries[i]; html += ``; } select.innerHTML = html; }); } function populateRefreshInterval(select) { let html = ''; html += ``; html += [30, 60, 90].map(val => { return ``; }).join(''); select.innerHTML = html; } function renderMetadataReaders(page, plugins) { let html = ''; const elem = page.querySelector('.metadataReaders'); if (plugins.length < 1) return elem.innerHTML = '', elem.classList.add('hide'), !1; html += `

${globalize.translate('LabelMetadataReaders')}

`; html += '
'; for (let i = 0; i < plugins.length; i++) { const plugin = plugins[i]; html += `
`; html += ''; html += '
'; html += '

'; html += plugin.Name; html += '

'; html += '
'; if (i > 0) { html += ``; } else if (plugins.length > 1) { html += ``; } html += '
'; } html += '
'; html += `
${globalize.translate('LabelMetadataReadersHelp')}
`; if (plugins.length < 2) { elem.classList.add('hide'); } else { elem.classList.remove('hide'); } elem.innerHTML = html; return true; } function renderMetadataSavers(page, metadataSavers) { let html = ''; const elem = page.querySelector('.metadataSavers'); if (!metadataSavers.length) return elem.innerHTML = '', elem.classList.add('hide'), false; html += `

${globalize.translate('LabelMetadataSavers')}

`; html += '
'; for (let i = 0; i < metadataSavers.length; i++) { const plugin = metadataSavers[i]; html += ``; } html += '
'; html += `
${globalize.translate('LabelMetadataSaversHelp')}
`; elem.innerHTML = html; elem.classList.remove('hide'); return true; } function getMetadataFetchersForTypeHtml(availableTypeOptions, libraryOptionsForType) { let html = ''; let plugins = availableTypeOptions.MetadataFetchers; plugins = getOrderedPlugins(plugins, libraryOptionsForType.MetadataFetcherOrder || []); if (!plugins.length) return html; html += '
'; html += '

' + globalize.translate('LabelTypeMetadataDownloaders', globalize.translate(availableTypeOptions.Type)) + '

'; html += '
'; plugins.forEach((plugin, index) => { html += '
'; const isChecked = libraryOptionsForType.MetadataFetchers ? libraryOptionsForType.MetadataFetchers.includes(plugin.Name) : plugin.DefaultEnabled; const checkedHtml = isChecked ? ' checked="checked"' : ''; html += ''; html += '
'; html += '

'; html += plugin.Name; html += '

'; html += '
'; if (index > 0) { html += ''; } else if (plugins.length > 1) { html += ''; } html += '
'; }); html += '
'; html += '
' + globalize.translate('LabelMetadataDownloadersHelp') + '
'; html += '
'; return html; } function getTypeOptions(allOptions, type) { const allTypeOptions = allOptions.TypeOptions || []; for (let i = 0; i < allTypeOptions.length; i++) { const typeOptions = allTypeOptions[i]; if (typeOptions.Type === type) return typeOptions; } return null; } function renderMetadataFetchers(page, availableOptions, libraryOptions) { let html = ''; const elem = page.querySelector('.metadataFetchers'); for (let i = 0; i < availableOptions.TypeOptions.length; i++) { const availableTypeOptions = availableOptions.TypeOptions[i]; html += getMetadataFetchersForTypeHtml(availableTypeOptions, getTypeOptions(libraryOptions, availableTypeOptions.Type) || {}); } elem.innerHTML = html; if (html) { elem.classList.remove('hide'); page.querySelector('.fldAutoRefreshInterval').classList.remove('hide'); page.querySelector('.fldMetadataLanguage').classList.remove('hide'); page.querySelector('.fldMetadataCountry').classList.remove('hide'); } else { elem.classList.add('hide'); page.querySelector('.fldAutoRefreshInterval').classList.add('hide'); page.querySelector('.fldMetadataLanguage').classList.add('hide'); page.querySelector('.fldMetadataCountry').classList.add('hide'); } return true; } function renderSubtitleFetchers(page, availableOptions, libraryOptions) { let html = ''; const elem = page.querySelector('.subtitleFetchers'); let plugins = availableOptions.SubtitleFetchers; plugins = getOrderedPlugins(plugins, libraryOptions.SubtitleFetcherOrder || []); if (!plugins.length) return html; html += `

${globalize.translate('LabelSubtitleDownloaders')}

`; html += '
'; for (let i = 0; i < plugins.length; i++) { const plugin = plugins[i]; html += `
`; const isChecked = libraryOptions.DisabledSubtitleFetchers ? !libraryOptions.DisabledSubtitleFetchers.includes(plugin.Name) : plugin.DefaultEnabled; const checkedHtml = isChecked ? ' checked="checked"' : ''; html += ``; html += '
'; html += '

'; html += plugin.Name; html += '

'; html += '
'; if (i > 0) { html += ``; } else if (plugins.length > 1) { html += ``; } html += '
'; } html += '
'; html += `
${globalize.translate('SubtitleDownloadersHelp')}
`; elem.innerHTML = html; } function getImageFetchersForTypeHtml(availableTypeOptions, libraryOptionsForType) { let html = ''; let plugins = availableTypeOptions.ImageFetchers; plugins = getOrderedPlugins(plugins, libraryOptionsForType.ImageFetcherOrder || []); if (!plugins.length) return html; html += '
'; html += '
'; html += '

' + globalize.translate('HeaderTypeImageFetchers', availableTypeOptions.Type) + '

'; const supportedImageTypes = availableTypeOptions.SupportedImageTypes || []; if (supportedImageTypes.length > 1 || supportedImageTypes.length === 1 && supportedImageTypes[0] !== 'Primary') { html += ''; } html += '
'; html += '
'; for (let i = 0; i < plugins.length; i++) { const plugin = plugins[i]; html += '
'; const isChecked = libraryOptionsForType.ImageFetchers ? libraryOptionsForType.ImageFetchers.includes(plugin.Name) : plugin.DefaultEnabled; const checkedHtml = isChecked ? ' checked="checked"' : ''; html += ''; html += '
'; html += '

'; html += plugin.Name; html += '

'; html += '
'; if (i > 0) { html += ''; } else if (plugins.length > 1) { html += ''; } html += '
'; } html += '
'; html += '
' + globalize.translate('LabelImageFetchersHelp') + '
'; html += '
'; return html; } function renderImageFetchers(page, availableOptions, libraryOptions) { let html = ''; const elem = page.querySelector('.imageFetchers'); for (let i = 0; i < availableOptions.TypeOptions.length; i++) { const availableTypeOptions = availableOptions.TypeOptions[i]; html += getImageFetchersForTypeHtml(availableTypeOptions, getTypeOptions(libraryOptions, availableTypeOptions.Type) || {}); } elem.innerHTML = html; if (html) { elem.classList.remove('hide'); page.querySelector('.chkDownloadImagesInAdvanceContainer').classList.remove('hide'); page.querySelector('.chkSaveLocalContainer').classList.remove('hide'); } else { elem.classList.add('hide'); page.querySelector('.chkDownloadImagesInAdvanceContainer').classList.add('hide'); page.querySelector('.chkSaveLocalContainer').classList.add('hide'); } return true; } function populateMetadataSettings(parent, contentType) { const isNewLibrary = parent.classList.contains('newlibrary'); return ApiClient.getJSON(ApiClient.getUrl('Libraries/AvailableOptions', { LibraryContentType: contentType, IsNewLibrary: isNewLibrary })).then(availableOptions => { currentAvailableOptions = availableOptions; parent.availableOptions = availableOptions; renderMetadataSavers(parent, availableOptions.MetadataSavers); renderMetadataReaders(parent, availableOptions.MetadataReaders); renderMetadataFetchers(parent, availableOptions, {}); renderSubtitleFetchers(parent, availableOptions, {}); renderImageFetchers(parent, availableOptions, {}); availableOptions.SubtitleFetchers.length ? parent.querySelector('.subtitleDownloadSettings').classList.remove('hide') : parent.querySelector('.subtitleDownloadSettings').classList.add('hide'); }).catch(() => { return Promise.resolve(); }); } function adjustSortableListElement(elem) { const btnSortable = elem.querySelector('.btnSortable'); const inner = btnSortable.querySelector('.material-icons'); if (elem.previousSibling) { btnSortable.title = globalize.translate('Up'); btnSortable.classList.add('btnSortableMoveUp'); btnSortable.classList.remove('btnSortableMoveDown'); inner.classList.remove('keyboard_arrow_down'); inner.classList.add('keyboard_arrow_up'); } else { btnSortable.title = globalize.translate('Down'); btnSortable.classList.remove('btnSortableMoveUp'); btnSortable.classList.add('btnSortableMoveDown'); inner.classList.remove('keyboard_arrow_up'); inner.classList.add('keyboard_arrow_down'); } } function showImageOptionsForType(type) { import('../imageOptionsEditor/imageOptionsEditor').then(({default: ImageOptionsEditor}) => { let typeOptions = getTypeOptions(currentLibraryOptions, type); if (!typeOptions) { typeOptions = { Type: type }; currentLibraryOptions.TypeOptions.push(typeOptions); } const availableOptions = getTypeOptions(currentAvailableOptions || {}, type); const imageOptionsEditor = new ImageOptionsEditor(); imageOptionsEditor.show(type, typeOptions, availableOptions); }); } function onImageFetchersContainerClick(e) { const btnImageOptionsForType = dom.parentWithClass(e.target, 'btnImageOptionsForType'); if (btnImageOptionsForType) { return void showImageOptionsForType(dom.parentWithClass(btnImageOptionsForType, 'imageFetcher').getAttribute('data-type')); } onSortableContainerClick.call(this, e); } function onSortableContainerClick(e) { const btnSortable = dom.parentWithClass(e.target, 'btnSortable'); if (btnSortable) { const li = dom.parentWithClass(btnSortable, 'sortableOption'); const list = dom.parentWithClass(li, 'paperList'); if (btnSortable.classList.contains('btnSortableMoveDown')) { const next = li.nextSibling; if (next) { li.parentNode.removeChild(li); next.parentNode.insertBefore(li, next.nextSibling); } } else { const prev = li.previousSibling; if (prev) { li.parentNode.removeChild(li); prev.parentNode.insertBefore(li, prev); } } Array.prototype.forEach.call(list.querySelectorAll('.sortableOption'), adjustSortableListElement); } } function bindEvents(parent) { parent.querySelector('.metadataReaders').addEventListener('click', onSortableContainerClick); parent.querySelector('.subtitleFetchers').addEventListener('click', onSortableContainerClick); parent.querySelector('.metadataFetchers').addEventListener('click', onSortableContainerClick); parent.querySelector('.imageFetchers').addEventListener('click', onImageFetchersContainerClick); } export async function embed(parent, contentType, libraryOptions) { currentLibraryOptions = { TypeOptions: [] }; currentAvailableOptions = null; const isNewLibrary = libraryOptions === null; isNewLibrary && parent.classList.add('newlibrary'); const response = await fetch('components/libraryoptionseditor/libraryoptionseditor.template.html'); const template = await response.text(); parent.innerHTML = globalize.translateHtml(template); populateRefreshInterval(parent.querySelector('#selectAutoRefreshInterval')); const promises = [populateLanguages(parent), populateCountries(parent.querySelector('#selectCountry'))]; Promise.all(promises).then(function() { return setContentType(parent, contentType).then(function() { libraryOptions && setLibraryOptions(parent, libraryOptions); bindEvents(parent); return; }); }); } export function setAdvancedVisible(parent, visible) { const elems = parent.querySelectorAll('.advanced'); for (let i = 0; i < elems.length; i++) { visible ? elems[i].classList.remove('advancedHide') : elems[i].classList.add('advancedHide'); } } export function setContentType(parent, contentType) { if (contentType === 'homevideos' || contentType === 'photos') { parent.querySelector('.chkEnablePhotosContainer').classList.remove('hide'); } else { parent.querySelector('.chkEnablePhotosContainer').classList.add('hide'); } if (contentType !== 'tvshows' && contentType !== 'movies' && contentType !== 'homevideos' && contentType !== 'musicvideos' && contentType !== 'mixed') { parent.querySelector('.chapterSettingsSection').classList.add('hide'); } else { parent.querySelector('.chapterSettingsSection').classList.remove('hide'); } if (contentType === 'tvshows') { parent.querySelector('.chkAutomaticallyGroupSeriesContainer').classList.remove('hide'); parent.querySelector('.fldSeasonZeroDisplayName').classList.remove('hide'); parent.querySelector('#txtSeasonZeroName').setAttribute('required', 'required'); } else { parent.querySelector('.chkAutomaticallyGroupSeriesContainer').classList.add('hide'); parent.querySelector('.fldSeasonZeroDisplayName').classList.add('hide'); parent.querySelector('#txtSeasonZeroName').removeAttribute('required'); } if (contentType === 'books' || contentType === 'boxsets' || contentType === 'playlists' || contentType === 'music') { parent.querySelector('.chkEnableEmbeddedTitlesContainer').classList.add('hide'); } else { parent.querySelector('.chkEnableEmbeddedTitlesContainer').classList.remove('hide'); } if (contentType === 'tvshows') { parent.querySelector('.chkEnableEmbeddedEpisodeInfosContainer').classList.remove('hide'); } else { parent.querySelector('.chkEnableEmbeddedEpisodeInfosContainer').classList.add('hide'); } return populateMetadataSettings(parent, contentType); } function setSubtitleFetchersIntoOptions(parent, options) { options.DisabledSubtitleFetchers = Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkSubtitleFetcher'), elem => { return !elem.checked; }), elem => { return elem.getAttribute('data-pluginname'); }); options.SubtitleFetcherOrder = Array.prototype.map.call(parent.querySelectorAll('.subtitleFetcherItem'), elem => { return elem.getAttribute('data-pluginname'); }); } function setMetadataFetchersIntoOptions(parent, options) { const sections = parent.querySelectorAll('.metadataFetcher'); for (let i = 0; i < sections.length; i++) { const section = sections[i]; const type = section.getAttribute('data-type'); let typeOptions = getTypeOptions(options, type); if (!typeOptions) { typeOptions = { Type: type }; options.TypeOptions.push(typeOptions); } typeOptions.MetadataFetchers = Array.prototype.map.call(Array.prototype.filter.call(section.querySelectorAll('.chkMetadataFetcher'), elem => { return elem.checked; }), elem => { return elem.getAttribute('data-pluginname'); }); typeOptions.MetadataFetcherOrder = Array.prototype.map.call(section.querySelectorAll('.metadataFetcherItem'), elem => { return elem.getAttribute('data-pluginname'); }); } } function setImageFetchersIntoOptions(parent, options) { const sections = parent.querySelectorAll('.imageFetcher'); for (let i = 0; i < sections.length; i++) { const section = sections[i]; const type = section.getAttribute('data-type'); let typeOptions = getTypeOptions(options, type); if (!typeOptions) { typeOptions = { Type: type }; options.TypeOptions.push(typeOptions); } typeOptions.ImageFetchers = Array.prototype.map.call(Array.prototype.filter.call(section.querySelectorAll('.chkImageFetcher'), elem => { return elem.checked; }), elem => { return elem.getAttribute('data-pluginname'); }); typeOptions.ImageFetcherOrder = Array.prototype.map.call(section.querySelectorAll('.imageFetcherItem'), elem => { return elem.getAttribute('data-pluginname'); }); } } function setImageOptionsIntoOptions(options) { const originalTypeOptions = (currentLibraryOptions || {}).TypeOptions || []; for (let i = 0; i < originalTypeOptions.length; i++) { const originalTypeOption = originalTypeOptions[i]; let typeOptions = getTypeOptions(options, originalTypeOption.Type); if (!typeOptions) { typeOptions = { Type: originalTypeOption.Type }; options.TypeOptions.push(typeOptions); } originalTypeOption.ImageOptions && (typeOptions.ImageOptions = originalTypeOption.ImageOptions); } } export function getLibraryOptions(parent) { const options = { EnableArchiveMediaFiles: false, EnablePhotos: parent.querySelector('.chkEnablePhotos').checked, EnableRealtimeMonitor: parent.querySelector('.chkEnableRealtimeMonitor').checked, ExtractChapterImagesDuringLibraryScan: parent.querySelector('.chkExtractChaptersDuringLibraryScan').checked, EnableChapterImageExtraction: parent.querySelector('.chkExtractChapterImages').checked, DownloadImagesInAdvance: parent.querySelector('#chkDownloadImagesInAdvance').checked, EnableInternetProviders: true, SaveLocalMetadata: parent.querySelector('#chkSaveLocal').checked, EnableAutomaticSeriesGrouping: parent.querySelector('.chkAutomaticallyGroupSeries').checked, PreferredMetadataLanguage: parent.querySelector('#selectLanguage').value, MetadataCountryCode: parent.querySelector('#selectCountry').value, SeasonZeroDisplayName: parent.querySelector('#txtSeasonZeroName').value, AutomaticRefreshIntervalDays: parseInt(parent.querySelector('#selectAutoRefreshInterval').value), EnableEmbeddedTitles: parent.querySelector('#chkEnableEmbeddedTitles').checked, EnableEmbeddedEpisodeInfos: parent.querySelector('#chkEnableEmbeddedEpisodeInfos').checked, SkipSubtitlesIfEmbeddedSubtitlesPresent: parent.querySelector('#chkSkipIfGraphicalSubsPresent').checked, SkipSubtitlesIfAudioTrackMatches: parent.querySelector('#chkSkipIfAudioTrackPresent').checked, SaveSubtitlesWithMedia: parent.querySelector('#chkSaveSubtitlesLocally').checked, RequirePerfectSubtitleMatch: parent.querySelector('#chkRequirePerfectMatch').checked, MetadataSavers: Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkMetadataSaver'), elem => { return elem.checked; }), elem => { return elem.getAttribute('data-pluginname'); }), TypeOptions: [] }; options.LocalMetadataReaderOrder = Array.prototype.map.call(parent.querySelectorAll('.localReaderOption'), elem => { return elem.getAttribute('data-pluginname'); }); options.SubtitleDownloadLanguages = Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkSubtitleLanguage'), elem => { return elem.checked; }), elem => { return elem.getAttribute('data-lang'); }); setSubtitleFetchersIntoOptions(parent, options); setMetadataFetchersIntoOptions(parent, options); setImageFetchersIntoOptions(parent, options); setImageOptionsIntoOptions(options); return options; } function getOrderedPlugins(plugins, configuredOrder) { plugins = plugins.slice(0); plugins.sort((a, b) => { return a = configuredOrder.indexOf(a.Name), b = configuredOrder.indexOf(b.Name), a < b ? -1 : a > b ? 1 : 0; }); return plugins; } export function setLibraryOptions(parent, options) { currentLibraryOptions = options; currentAvailableOptions = parent.availableOptions; parent.querySelector('#selectLanguage').value = options.PreferredMetadataLanguage || ''; parent.querySelector('#selectCountry').value = options.MetadataCountryCode || ''; parent.querySelector('#selectAutoRefreshInterval').value = options.AutomaticRefreshIntervalDays || '0'; parent.querySelector('#txtSeasonZeroName').value = options.SeasonZeroDisplayName || 'Specials'; parent.querySelector('.chkEnablePhotos').checked = options.EnablePhotos; parent.querySelector('.chkEnableRealtimeMonitor').checked = options.EnableRealtimeMonitor; parent.querySelector('.chkExtractChaptersDuringLibraryScan').checked = options.ExtractChapterImagesDuringLibraryScan; parent.querySelector('.chkExtractChapterImages').checked = options.EnableChapterImageExtraction; parent.querySelector('#chkDownloadImagesInAdvance').checked = options.DownloadImagesInAdvance; parent.querySelector('#chkSaveLocal').checked = options.SaveLocalMetadata; parent.querySelector('.chkAutomaticallyGroupSeries').checked = options.EnableAutomaticSeriesGrouping; parent.querySelector('#chkEnableEmbeddedTitles').checked = options.EnableEmbeddedTitles; parent.querySelector('#chkEnableEmbeddedEpisodeInfos').checked = options.EnableEmbeddedEpisodeInfos; parent.querySelector('#chkSkipIfGraphicalSubsPresent').checked = options.SkipSubtitlesIfEmbeddedSubtitlesPresent; parent.querySelector('#chkSaveSubtitlesLocally').checked = options.SaveSubtitlesWithMedia; parent.querySelector('#chkSkipIfAudioTrackPresent').checked = options.SkipSubtitlesIfAudioTrackMatches; parent.querySelector('#chkRequirePerfectMatch').checked = options.RequirePerfectSubtitleMatch; Array.prototype.forEach.call(parent.querySelectorAll('.chkMetadataSaver'), elem => { elem.checked = options.MetadataSavers ? options.MetadataSavers.includes(elem.getAttribute('data-pluginname')) : elem.getAttribute('data-defaultenabled') === 'true'; }); Array.prototype.forEach.call(parent.querySelectorAll('.chkSubtitleLanguage'), elem => { elem.checked = !!options.SubtitleDownloadLanguages && options.SubtitleDownloadLanguages.includes(elem.getAttribute('data-lang')); }); renderMetadataReaders(parent, getOrderedPlugins(parent.availableOptions.MetadataReaders, options.LocalMetadataReaderOrder || [])); renderMetadataFetchers(parent, parent.availableOptions, options); renderImageFetchers(parent, parent.availableOptions, options); renderSubtitleFetchers(parent, parent.availableOptions, options); } let currentLibraryOptions; let currentAvailableOptions; /* eslint-enable indent */ export default { embed: embed, setContentType: setContentType, getLibraryOptions: getLibraryOptions, setLibraryOptions: setLibraryOptions, setAdvancedVisible: setAdvancedVisible };