import escapeHtml from 'escape-html'; import loading from '../loading/loading'; import dialogHelper from '../dialogHelper/dialogHelper'; import dom from '../../scripts/dom'; import globalize from '../../lib/globalize'; import '../listview/listview.scss'; import '../../elements/emby-input/emby-input'; import '../../elements/emby-button/paper-icon-button-light'; import './directorybrowser.scss'; import '../formdialog.scss'; import '../../elements/emby-button/emby-button'; import alert from '../alert'; function getSystemInfo() { return systemInfo ? Promise.resolve(systemInfo) : ApiClient.getPublicSystemInfo().then( info => { systemInfo = info; return info; } ); } function onDialogClosed() { loading.hide(); } function refreshDirectoryBrowser(page, path, fileOptions, updatePathOnError) { if (path && typeof path !== 'string') { throw new Error('invalid path'); } loading.show(); const promises = []; if (path) { promises.push(ApiClient.getDirectoryContents(path, fileOptions)); promises.push(ApiClient.getParentPath(path)); } else { promises.push(ApiClient.getDrives()); } Promise.all(promises).then( responses => { const folders = responses[0]; const parentPath = (responses[1] ? JSON.parse(responses[1]) : '') || ''; let html = ''; page.querySelector('.results').scrollTop = 0; page.querySelector('#txtDirectoryPickerPath').value = path || ''; if (path) { html += getItem('lnkPath lnkDirectory', '', parentPath, '...'); } for (let i = 0, length = folders.length; i < length; i++) { const folder = folders[i]; const cssClass = folder.Type === 'File' ? 'lnkPath lnkFile' : 'lnkPath lnkDirectory'; html += getItem(cssClass, folder.Type, folder.Path, folder.Name); } page.querySelector('.results').innerHTML = html; loading.hide(); }, () => { if (updatePathOnError) { page.querySelector('#txtDirectoryPickerPath').value = ''; page.querySelector('.results').innerHTML = ''; loading.hide(); } } ); } function getItem(cssClass, type, path, name) { let html = ''; html += `
`; html += '
'; html += '
'; html += escapeHtml(name); html += '
'; html += '
'; html += ''; html += '
'; return html; } function getEditorHtml(options, systemInfo) { let html = ''; html += '
'; html += '
'; if (!options.pathReadOnly && (options.instruction || systemInfo.OperatingSystem)) { const instruction = options.instruction ? `${escapeHtml(options.instruction)}

` : ''; html += '
'; html += instruction; if (systemInfo.OperatingSystem.toLowerCase() === 'bsd') { html += '
'; html += '
'; html += globalize.translate('MessageDirectoryPickerBSDInstruction'); html += '
'; } else if (systemInfo.OperatingSystem.toLowerCase() === 'linux') { html += '
'; html += '
'; html += globalize.translate('MessageDirectoryPickerLinuxInstruction'); html += '
'; } html += '
'; } html += '
'; html += '
'; html += '
'; let labelKey; if (options.includeFiles !== true) { labelKey = 'LabelFolder'; } else { labelKey = 'LabelPath'; } const readOnlyAttribute = options.pathReadOnly ? ' readonly' : ''; html += ``; html += '
'; if (!readOnlyAttribute) { html += ``; } html += '
'; if (!readOnlyAttribute) { html += '
'; } if (options.enableNetworkSharePath) { html += '
'; html += ``; html += '
'; html += globalize.translate('LabelOptionalNetworkPathHelp', '\\\\server', '\\\\192.168.1.101'); html += '
'; html += '
'; } html += '
'; html += ``; html += '
'; html += '
'; html += '
'; html += '
'; html += ''; return html; } function alertText(text) { alertTextWithOptions({ text: text }); } function alertTextWithOptions(options) { alert(options); } function validatePath(path, validateWriteable, apiClient) { return apiClient.ajax({ type: 'POST', url: apiClient.getUrl('Environment/ValidatePath'), data: JSON.stringify({ ValidateWriteable: validateWriteable, Path: path }), contentType: 'application/json' }).catch(response => { if (response) { if (response.status === 404) { alertText(globalize.translate('PathNotFound')); return Promise.reject(); } if (response.status === 500) { if (validateWriteable) { alertText(globalize.translate('WriteAccessRequired')); } else { alertText(globalize.translate('PathNotFound')); } return Promise.reject(); } } return Promise.resolve(); }); } function initEditor(content, options, fileOptions) { content.addEventListener('click', e => { const lnkPath = dom.parentWithClass(e.target, 'lnkPath'); if (lnkPath) { const path = lnkPath.getAttribute('data-path'); if (lnkPath.classList.contains('lnkFile')) { content.querySelector('#txtDirectoryPickerPath').value = path; } else { refreshDirectoryBrowser(content, path, fileOptions, true); } } }); content.addEventListener('click', e => { if (dom.parentWithClass(e.target, 'btnRefreshDirectories')) { const path = content.querySelector('#txtDirectoryPickerPath').value; refreshDirectoryBrowser(content, path, fileOptions); } }); content.addEventListener('change', e => { const txtDirectoryPickerPath = dom.parentWithTag(e.target, 'INPUT'); if (txtDirectoryPickerPath && txtDirectoryPickerPath.id === 'txtDirectoryPickerPath') { refreshDirectoryBrowser(content, txtDirectoryPickerPath.value, fileOptions); } }); content.querySelector('form').addEventListener('submit', function(e) { if (options.callback) { let networkSharePath = this.querySelector('#txtNetworkPath'); networkSharePath = networkSharePath ? networkSharePath.value : null; const path = this.querySelector('#txtDirectoryPickerPath').value; validatePath(path, options.validateWriteable, ApiClient).then(options.callback(path, networkSharePath)); } e.preventDefault(); e.stopPropagation(); return false; }); } function getDefaultPath(options) { if (options.path) { return Promise.resolve(options.path); } else { return ApiClient.getJSON(ApiClient.getUrl('Environment/DefaultDirectoryBrowser')).then( result => { return result.Path || ''; }, () => { return ''; } ); } } let systemInfo; class DirectoryBrowser { currentDialog; show = options => { options = options || {}; const fileOptions = { includeDirectories: true }; if (options.includeDirectories != null) { fileOptions.includeDirectories = options.includeDirectories; } if (options.includeFiles != null) { fileOptions.includeFiles = options.includeFiles; } Promise.all([getSystemInfo(), getDefaultPath(options)]).then( responses => { const fetchedSystemInfo = responses[0]; const fetchedInitialPath = responses[1]; const dlg = dialogHelper.createDialog({ size: 'small', removeOnClose: true, scrollY: false }); dlg.classList.add('ui-body-a'); dlg.classList.add('background-theme-a'); dlg.classList.add('directoryPicker'); dlg.classList.add('formDialog'); let html = ''; html += '
'; html += ``; html += '

'; html += escapeHtml(options.header || '') || globalize.translate('HeaderSelectPath'); html += '

'; html += '
'; html += getEditorHtml(options, fetchedSystemInfo); dlg.innerHTML = html; initEditor(dlg, options, fileOptions); dlg.addEventListener('close', onDialogClosed); dialogHelper.open(dlg); dlg.querySelector('.btnCloseDialog').addEventListener('click', () => { dialogHelper.close(dlg); }); this.currentDialog = dlg; dlg.querySelector('#txtDirectoryPickerPath').value = fetchedInitialPath; const txtNetworkPath = dlg.querySelector('#txtNetworkPath'); if (txtNetworkPath) { txtNetworkPath.value = options.networkSharePath || ''; } if (!options.pathReadOnly) { refreshDirectoryBrowser(dlg, fetchedInitialPath, fileOptions, true); } } ); }; close = () => { if (this.currentDialog) { dialogHelper.close(this.currentDialog); } }; } export default DirectoryBrowser;