define(['apphost', 'globalize', 'connectionManager', 'layoutManager', 'shell', 'focusManager', 'scrollHelper', 'appSettings', 'paper-icon-button-light', 'formDialogStyle'], function (appHost, globalize, connectionManager, layoutManager, shell, focusManager, scrollHelper, appSettings) { var currentDialogOptions; function submitJob(dlg, apiClient, userId, syncOptions, form, dialogHelper) { if (!userId) { throw new Error('userId cannot be null'); } if (!syncOptions) { throw new Error('syncOptions cannot be null'); } if (!form) { throw new Error('form cannot be null'); } var selectSyncTarget = form.querySelector('#selectSyncTarget'); var target = selectSyncTarget ? selectSyncTarget.value : null; if (!target) { require(['toast'], function (toast) { toast(globalize.translate('sharedcomponents#PleaseSelectDeviceToSyncTo')); }); return false; } var options = { userId: userId, TargetId: target, ParentId: syncOptions.ParentId, Category: syncOptions.Category }; setJobValues(options, form); if (syncOptions.items && syncOptions.items.length) { options.ItemIds = (syncOptions.items || []).map(function (i) { return i.Id || i; }).join(','); } apiClient.ajax({ type: "POST", url: apiClient.getUrl("Sync/Jobs"), data: JSON.stringify(options), contentType: "application/json", dataType: 'json' }).then(function () { dialogHelper.close(dlg); require(['toast'], function (toast) { var msg = target == apiClient.deviceId() ? globalize.translate('sharedcomponents#DownloadScheduled') : globalize.translate('sharedcomponents#SyncJobCreated'); toast(msg); }); }); return true; } function submitQuickSyncJob(apiClient, userId, targetId, syncOptions) { if (!userId) { throw new Error('userId cannot be null'); } if (!syncOptions) { throw new Error('syncOptions cannot be null'); } if (!targetId) { throw new Error('targetId cannot be null'); } var options = { userId: userId, TargetId: targetId, ParentId: syncOptions.ParentId, Category: syncOptions.Category, Quality: syncOptions.Quality, Bitrate: syncOptions.Bitrate }; if (syncOptions.items && syncOptions.items.length) { options.ItemIds = (syncOptions.items || []).map(function (i) { return i.Id || i; }).join(','); } return apiClient.ajax({ type: "POST", url: apiClient.getUrl("Sync/Jobs"), data: JSON.stringify(options), contentType: "application/json", dataType: 'json' }).then(function () { require(['toast'], function (toast) { var msg = targetId == apiClient.deviceId() ? globalize.translate('sharedcomponents#DownloadScheduled') : globalize.translate('sharedcomponents#SyncJobCreated'); toast(msg); }); }); } function setJobValues(job, form) { var txtBitrate = form.querySelector('#txtBitrate'); var bitrate = txtBitrate ? txtBitrate.value : null; if (bitrate) { bitrate = parseFloat(bitrate) * 1000000; } job.Bitrate = bitrate; var txtSyncJobName = form.querySelector('#txtSyncJobName'); if (txtSyncJobName) { job.Name = txtSyncJobName.value; } var selectQuality = form.querySelector('#selectQuality'); if (selectQuality) { job.Quality = selectQuality.value; } var selectProfile = form.querySelector('#selectProfile'); if (selectProfile) { job.Profile = selectProfile.value; } var txtItemLimit = form.querySelector('#txtItemLimit'); if (txtItemLimit) { job.ItemLimit = txtItemLimit.value || null; } var chkSyncNewContent = form.querySelector('#chkSyncNewContent'); if (chkSyncNewContent) { job.SyncNewContent = chkSyncNewContent.checked; } var chkUnwatchedOnly = form.querySelector('#chkUnwatchedOnly'); if (chkUnwatchedOnly) { job.UnwatchedOnly = chkUnwatchedOnly.checked; } } function renderForm(options) { return new Promise(function (resolve, reject) { require(['emby-checkbox', 'emby-input', 'emby-select'], function () { appHost.appInfo().then(function (appInfo) { renderFormInternal(options, appInfo, resolve); }); }); }); } function onHelpLinkClick(e) { shell.openUrl(this.href); e.preventDefault(); return false; } function renderFormInternal(options, appInfo, resolve) { var elem = options.elem; var dialogOptions = options.dialogOptions; var targets = dialogOptions.Targets; var html = ''; var targetContainerClass = options.isLocalSync ? ' hide' : ''; if (options.showName || dialogOptions.Options.indexOf('Name') != -1) { html += '
'; html += ''; html += '
'; } if (options.readOnlySyncTarget) { html += '
'; html += ''; html += '
'; } else { html += '
'; html += ''; if (!targets.length) { html += '
' + globalize.translate('sharedcomponents#LabelSyncNoTargetsHelp') + '
'; html += '
' + globalize.translate('sharedcomponents#LearnMore') + '
'; } html += '
'; } html += '
'; html += ''; html += '
'; html += '
'; html += '
'; html += ''; html += '
'; html += '
'; html += '
'; html += ''; html += '
'; if (dialogOptions.Options.indexOf('UnwatchedOnly') != -1) { html += '
'; html += ''; html += '
' + globalize.translate('sharedcomponents#SyncUnwatchedVideosOnlyHelp') + '
'; html += '
'; } if (dialogOptions.Options.indexOf('SyncNewContent') != -1) { html += '
'; html += ''; html += '
' + globalize.translate('sharedcomponents#AutomaticallySyncNewContentHelp') + '
'; html += '
'; } if (dialogOptions.Options.indexOf('ItemLimit') != -1) { html += '
'; html += ''; html += '
' + globalize.translate('sharedcomponents#LabelItemLimitHelp') + '
'; html += '
'; } //html += ''; //html += ''; elem.innerHTML = html; var selectSyncTarget = elem.querySelector('#selectSyncTarget'); if (selectSyncTarget) { selectSyncTarget.addEventListener('change', function () { loadQualityOptions(elem, this.value, options.dialogOptionsFn).then(resolve); }); selectSyncTarget.dispatchEvent(new CustomEvent('change', { bubbles: true })); } var selectProfile = elem.querySelector('#selectProfile'); if (selectProfile) { selectProfile.addEventListener('change', function () { onProfileChange(elem, this.value); }); selectProfile.dispatchEvent(new CustomEvent('change', { bubbles: true })); } var selectQuality = elem.querySelector('#selectQuality'); if (selectQuality) { selectQuality.addEventListener('change', function () { onQualityChange(elem, this.value); }); selectQuality.dispatchEvent(new CustomEvent('change', { bubbles: true })); } var lnkLearnMore = elem.querySelector('.lnkLearnMore'); if (lnkLearnMore) { lnkLearnMore.addEventListener('click', onHelpLinkClick); } // This isn't ideal, but allow time for the change handlers above to run setTimeout(function () { focusManager.autoFocus(elem); }, 100); } function showSyncMenu(options) { return new Promise(function (resolve, reject) { require(["registrationservices", 'dialogHelper', 'formDialogStyle'], function (registrationServices, dialogHelper) { registrationServices.validateFeature('sync').then(function () { showSyncMenuInternal(dialogHelper, options).then(resolve, reject); }, reject); }); }); } function enableAutoSync(options) { if (!options.isLocalSync) { return false; } var firstItem = (options.items || [])[0] || {}; if (firstItem.Type == 'Audio') { return true; } if (firstItem.Type == 'MusicAlbum') { return true; } if (firstItem.Type == 'MusicArtist') { return true; } if (firstItem.Type == 'MusicGenre') { return true; } return false; } function showSyncMenuInternal(dialogHelper, options) { var apiClient = connectionManager.getApiClient(options.serverId); var userId = apiClient.getCurrentUserId(); if (enableAutoSync(options)) { return submitQuickSyncJob(apiClient, userId, apiClient.deviceId(), { items: options.items, Quality: 'custom', Bitrate: appSettings.maxStaticMusicBitrate() }); } var dialogOptionsQuery = { UserId: userId, ItemIds: (options.items || []).map(function (i) { return i.Id || i; }).join(','), ParentId: options.ParentId, Category: options.Category }; return apiClient.getJSON(apiClient.getUrl('Sync/Options', dialogOptionsQuery)).then(function (dialogOptions) { currentDialogOptions = dialogOptions; var dlgElementOptions = { removeOnClose: true, scrollY: false, autoFocus: false }; if (layoutManager.tv) { dlgElementOptions.size = 'fullscreen'; } else { dlgElementOptions.size = 'small'; } var dlg = dialogHelper.createDialog(dlgElementOptions); dlg.classList.add('formDialog'); var html = ''; html += '
'; html += ''; html += '

'; html += globalize.translate('sharedcomponents#Sync'); html += '

'; html += ''; html += '
'; html += '
'; html += '
'; html += '
'; html += '
'; html += '
'; html += ''; html += '
'; html += '
'; html += '
'; html += '
'; dlg.innerHTML = html; dlg.querySelector('.lnkHelp').addEventListener('click', onHelpLinkClick); var submitted = false; dlg.querySelector('form').addEventListener('submit', function (e) { submitted = submitJob(dlg, apiClient, userId, options, this, dialogHelper); e.preventDefault(); return false; }); dlg.querySelector('.btnCancel').addEventListener('click', function () { dialogHelper.close(dlg); }); if (layoutManager.tv) { scrollHelper.centerFocus.on(dlg.querySelector('.formDialogContent'), false); } var promise = dialogHelper.open(dlg); renderForm({ elem: dlg.querySelector('.formFields'), dialogOptions: dialogOptions, dialogOptionsFn: getTargetDialogOptionsFn(apiClient, dialogOptionsQuery), isLocalSync: options.isLocalSync }); return promise.then(function () { if (submitted) { return Promise.resolve(); } return Promise.reject(); }); }); } function getTargetDialogOptionsFn(apiClient, query) { return function (targetId) { query.TargetId = targetId; return apiClient.getJSON(apiClient.getUrl('Sync/Options', query)); }; } function setQualityFieldVisible(form, visible) { var fldQuality = form.querySelector('.fldQuality'); var selectQuality = form.querySelector('#selectQuality'); if (visible) { if (fldQuality) { fldQuality.classList.remove('hide'); } if (selectQuality) { selectQuality.setAttribute('required', 'required'); } } else { if (fldQuality) { fldQuality.classList.add('hide'); } if (selectQuality) { selectQuality.removeAttribute('required'); } } } function onProfileChange(form, profileId) { var options = currentDialogOptions || {}; var option = (options.ProfileOptions || []).filter(function (o) { return o.Id == profileId; })[0]; var qualityOptions = options.QualityOptions || []; if (option) { form.querySelector('.profileDescription').innerHTML = option.Description || ''; setQualityFieldVisible(form, qualityOptions.length > 0 && option.EnableQualityOptions && options.Options.indexOf('Quality') != -1); } else { form.querySelector('.profileDescription').innerHTML = ''; setQualityFieldVisible(form, qualityOptions.length > 0 && options.Options.indexOf('Quality') != -1); } } function onQualityChange(form, qualityId) { var options = currentDialogOptions || {}; var option = (options.QualityOptions || []).filter(function (o) { return o.Id == qualityId; })[0]; var qualityDescription = form.querySelector('.qualityDescription'); if (option) { qualityDescription.innerHTML = option.Description || ''; } else { qualityDescription.innerHTML = ''; } var fldBitrate = form.querySelector('.fldBitrate'); var txtBitrate = form.querySelector('#txtBitrate'); if (qualityId == 'custom') { if (fldBitrate) { fldBitrate.classList.remove('hide'); } if (txtBitrate) { txtBitrate.setAttribute('required', 'required'); } } else { if (fldBitrate) { fldBitrate.classList.add('hide'); } if (txtBitrate) { txtBitrate.removeAttribute('required'); } } } function renderTargetDialogOptions(form, options) { currentDialogOptions = options; var fldProfile = form.querySelector('.fldProfile'); var selectProfile = form.querySelector('#selectProfile'); if (options.ProfileOptions.length && options.Options.indexOf('Profile') != -1) { if (fldProfile) { fldProfile.classList.remove('hide'); } if (selectProfile) { selectProfile.setAttribute('required', 'required'); } } else { if (fldProfile) { fldProfile.classList.add('hide'); } if (selectProfile) { selectProfile.removeAttribute('required'); } } setQualityFieldVisible(form, options.QualityOptions.length > 0); if (selectProfile) { selectProfile.innerHTML = options.ProfileOptions.map(function (o) { var selectedAttribute = o.IsDefault ? ' selected="selected"' : ''; return ''; }).join(''); selectProfile.dispatchEvent(new CustomEvent('change', { bubbles: true })); } var selectQuality = form.querySelector('#selectQuality'); if (selectQuality) { selectQuality.innerHTML = options.QualityOptions.map(function (o) { var selectedAttribute = o.IsDefault ? ' selected="selected"' : ''; return ''; }).join(''); selectQuality.dispatchEvent(new CustomEvent('change', { bubbles: true })); } } function loadQualityOptions(form, targetId, dialogOptionsFn) { return dialogOptionsFn(targetId).then(function (options) { return renderTargetDialogOptions(form, options); }); } return { showMenu: showSyncMenu, renderForm: renderForm, setJobValues: setJobValues }; });