1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00
jellyfin-web/dashboard-ui/scripts/sync.js

413 lines
14 KiB
JavaScript
Raw Normal View History

2016-05-07 15:41:10 -04:00
define(['apphost', 'jQuery', 'paper-icon-button-light'], function (appHost, $) {
2015-03-15 00:17:35 -04:00
var currentDialogOptions;
2016-03-23 15:03:17 -04:00
function submitJob(dlg, userId, syncOptions, form, dialogHelper) {
2014-12-12 22:56:30 -05:00
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');
}
2014-07-22 12:36:34 -04:00
2014-12-30 11:36:49 -05:00
var target = $('#selectSyncTarget', form).val();
2014-07-26 13:30:15 -04:00
if (!target) {
2014-07-22 12:36:34 -04:00
2016-02-25 01:38:12 -05:00
require(['toast'], function (toast) {
toast(Globalize.translate('MessagePleaseSelectDeviceToSyncTo'));
});
2016-08-18 01:56:10 -04:00
return false;
2014-07-22 12:36:34 -04:00
}
var options = {
userId: userId,
2014-07-26 13:30:15 -04:00
TargetId: target,
2014-07-22 12:36:34 -04:00
2014-12-18 23:20:07 -05:00
ParentId: syncOptions.ParentId,
Category: syncOptions.Category
2014-07-22 12:36:34 -04:00
};
2015-03-15 15:10:27 -04:00
setJobValues(options, form);
2014-12-30 11:36:49 -05:00
if (syncOptions.items && syncOptions.items.length) {
options.ItemIds = (syncOptions.items || []).map(function (i) {
return i.Id || i;
}).join(',');
}
2014-07-22 12:36:34 -04:00
ApiClient.ajax({
type: "POST",
url: ApiClient.getUrl("Sync/Jobs"),
data: JSON.stringify(options),
2015-08-15 16:33:53 -04:00
contentType: "application/json",
dataType: 'json'
2014-07-22 12:36:34 -04:00
2015-12-14 10:43:03 -05:00
}).then(function () {
2014-07-22 12:36:34 -04:00
2016-03-23 15:03:17 -04:00
dialogHelper.close(dlg);
2016-02-25 01:38:12 -05:00
require(['toast'], function (toast) {
2016-08-18 01:56:10 -04:00
var msg = target == ApiClient.deviceId() ? Globalize.translate('MessageDownloadScheduled') : Globalize.translate('MessageSyncJobCreated');
toast(msg);
2016-02-25 01:38:12 -05:00
});
2014-07-22 12:36:34 -04:00
});
2016-08-18 01:56:10 -04:00
return true;
2014-07-22 12:36:34 -04:00
}
2015-03-15 15:10:27 -04:00
function setJobValues(job, form) {
var bitrate = $('#txtBitrate', form).val() || null;
if (bitrate) {
bitrate = parseFloat(bitrate) * 1000000;
}
job.Name = $('#txtSyncJobName', form).val();
job.Quality = $('#selectQuality', form).val() || null;
job.Profile = $('#selectProfile', form).val() || null;
job.Bitrate = bitrate;
job.ItemLimit = $('#txtItemLimit', form).val() || null;
job.SyncNewContent = $('#chkSyncNewContent', form).checked();
job.UnwatchedOnly = $('#chkUnwatchedOnly', form).checked();
}
2015-03-15 00:17:35 -04:00
function renderForm(options) {
2015-12-14 10:43:03 -05:00
return new Promise(function (resolve, reject) {
2016-08-23 01:08:07 -04:00
require(['emby-checkbox', 'emby-input', 'emby-select'], function () {
2016-04-18 14:50:29 -04:00
appHost.appInfo().then(function (appInfo) {
renderFormInternal(options, appInfo, resolve);
});
2015-12-14 10:43:03 -05:00
});
});
}
2016-04-18 14:50:29 -04:00
function renderFormInternal(options, appInfo, resolve) {
2015-12-14 10:43:03 -05:00
2015-03-15 00:17:35 -04:00
var elem = options.elem;
var dialogOptions = options.dialogOptions;
var targets = dialogOptions.Targets;
var html = '';
2016-08-23 01:08:07 -04:00
var targetContainerClass = options.isLocalSync ? ' hide' : '';
2015-03-15 00:24:43 -04:00
if (options.showName || dialogOptions.Options.indexOf('Name') != -1) {
2015-03-15 00:17:35 -04:00
2016-08-23 01:08:07 -04:00
html += '<div class="inputContainer' + targetContainerClass + '">';
2016-06-11 11:56:15 -04:00
html += '<input is="emby-input" type="text" id="txtSyncJobName" class="txtSyncJobName" required="required" label="' + Globalize.translate('LabelSyncJobName') + '"/>';
2015-08-17 12:52:56 -04:00
html += '</div>';
2015-03-15 00:17:35 -04:00
}
2015-03-15 00:39:29 -04:00
if (options.readOnlySyncTarget) {
2016-08-23 01:08:07 -04:00
html += '<div class="inputContainer' + targetContainerClass + '">';
2016-06-11 11:56:15 -04:00
html += '<input is="emby-input" type="text" id="selectSyncTarget" readonly label="' + Globalize.translate('LabelSyncTo') + '"/>';
html += '</div>';
2015-03-15 00:39:29 -04:00
} else {
2016-08-23 01:08:07 -04:00
html += '<div class="selectContainer' + targetContainerClass + '">';
html += '<select is="emby-select" id="selectSyncTarget" required="required" label="' + Globalize.translate('LabelSyncTo') + '">';
2015-03-15 00:17:35 -04:00
2015-03-15 00:39:29 -04:00
html += targets.map(function (t) {
2015-03-15 00:17:35 -04:00
2016-04-18 14:50:29 -04:00
var isSelected = t.Id == appInfo.deviceId;
var selectedHtml = isSelected ? ' selected="selected"' : '';
return '<option' + selectedHtml + ' value="' + t.Id + '">' + t.Name + '</option>';
2015-03-15 00:17:35 -04:00
2015-03-15 00:39:29 -04:00
}).join('');
html += '</select>';
if (!targets.length) {
html += '<div class="fieldDescription">' + Globalize.translate('LabelSyncNoTargetsHelp') + '</div>';
html += '<div class="fieldDescription"><a href="https://github.com/MediaBrowser/Wiki/wiki/Sync" target="_blank">' + Globalize.translate('ButtonLearnMore') + '</a></div>';
}
2016-08-23 01:08:07 -04:00
html += '</div>';
2015-03-15 00:17:35 -04:00
}
2016-08-23 01:08:07 -04:00
html += '<div class="fldProfile selectContainer" style="display:none;">';
html += '<select is="emby-select" id="selectProfile" label="' + Globalize.translate('LabelProfile') + '">';
2015-03-15 00:17:35 -04:00
html += '</select>';
html += '<div class="fieldDescription profileDescription"></div>';
html += '</div>';
2016-08-23 01:08:07 -04:00
html += '<div class="fldQuality selectContainer" style="display:none;">';
html += '<select is="emby-select" id="selectQuality" data-mini="true" required="required" label="' + Globalize.translate('LabelQuality') + '">';
2015-03-15 00:17:35 -04:00
html += '</select>';
html += '<div class="fieldDescription qualityDescription"></div>';
html += '</div>';
2016-08-23 01:08:07 -04:00
html += '<div class="fldBitrate inputContainer" style="display:none;">';
2016-06-11 11:56:15 -04:00
html += '<input is="emby-input" type="number" step=".1" min=".1" id="txtBitrate" label="' + Globalize.translate('LabelBitrateMbps') + '"/>';
2015-03-15 00:17:35 -04:00
html += '</div>';
if (dialogOptions.Options.indexOf('UnwatchedOnly') != -1) {
2016-08-06 10:07:44 -04:00
html += '<div class="checkboxContainer checkboxContainer-withDescription">';
2016-06-11 11:56:15 -04:00
html += '<label>';
html += '<input is="emby-checkbox" type="checkbox" id="chkUnwatchedOnly"/>';
html += '<span>' + Globalize.translate('OptionSyncUnwatchedVideosOnly') + '</span>';
html += '</label>';
html += '<div class="fieldDescription checkboxFieldDescription">' + Globalize.translate('OptionSyncUnwatchedVideosOnlyHelp') + '</div>';
2015-03-15 00:17:35 -04:00
html += '</div>';
}
2016-08-23 01:08:07 -04:00
if (dialogOptions.Options.indexOf('SyncNewContent') != -1) {
html += '<div class="checkboxContainer checkboxContainer-withDescription">';
html += '<label>';
html += '<input is="emby-checkbox" type="checkbox" id="chkSyncNewContent"/>';
html += '<span>' + Globalize.translate('OptionAutomaticallySyncNewContent') + '</span>';
html += '</label>';
html += '<div class="fieldDescription checkboxFieldDescription">' + Globalize.translate('OptionAutomaticallySyncNewContentHelp') + '</div>';
2015-03-15 00:17:35 -04:00
html += '</div>';
2016-08-23 01:08:07 -04:00
}
if (dialogOptions.Options.indexOf('ItemLimit') != -1) {
html += '<div class="inputContainer">';
html += '<input is="emby-input" type="number" step="1" min="1" id="txtItemLimit" label="' + Globalize.translate('LabelItemLimit') + '"/>';
html += '<div class="fieldDescription">' + Globalize.translate('LabelItemLimitHelp') + '</div>';
2016-07-02 14:05:40 -04:00
html += '</div>';
2015-03-15 00:17:35 -04:00
}
//html += '</div>';
//html += '</div>';
2016-08-16 14:54:08 -04:00
elem.innerHTML = html;
2015-03-15 00:17:35 -04:00
$('#selectSyncTarget', elem).on('change', function () {
loadQualityOptions(elem, this.value, options.dialogOptionsFn).then(resolve);
2015-03-15 00:17:35 -04:00
}).trigger('change');
$('#selectProfile', elem).on('change', function () {
onProfileChange(elem, this.value);
}).trigger('change');
$('#selectQuality', elem).on('change', function () {
onQualityChange(elem, this.value);
}).trigger('change');
}
2014-12-12 22:56:30 -05:00
function showSyncMenu(options) {
2016-08-16 01:34:36 -04:00
return new Promise(function (resolve, reject) {
2016-08-18 01:56:10 -04:00
require(["registrationservices", 'dialogHelper', 'formDialogStyle'], function (registrationServices, dialogHelper) {
2016-08-16 01:34:36 -04:00
registrationServices.validateFeature('sync').then(function () {
showSyncMenuInternal(dialogHelper, options).then(resolve, reject);
}, reject);
2015-07-29 22:08:35 -04:00
});
});
}
2016-08-16 01:34:36 -04:00
function showSyncMenuInternal(dialogHelper, options) {
2014-07-22 12:36:34 -04:00
2016-08-16 01:34:36 -04:00
var userId = Dashboard.getCurrentUserId();
2014-12-18 23:20:07 -05:00
2016-08-16 01:34:36 -04:00
var dialogOptionsQuery = {
UserId: userId,
ItemIds: (options.items || []).map(function (i) {
return i.Id || i;
}).join(','),
2014-12-17 00:30:31 -05:00
2016-08-16 01:34:36 -04:00
ParentId: options.ParentId,
Category: options.Category
};
2014-07-22 12:36:34 -04:00
2016-08-16 01:34:36 -04:00
return ApiClient.getJSON(ApiClient.getUrl('Sync/Options', dialogOptionsQuery)).then(function (dialogOptions) {
2014-07-22 12:36:34 -04:00
2016-08-16 01:34:36 -04:00
currentDialogOptions = dialogOptions;
2014-07-22 12:36:34 -04:00
2016-08-16 01:34:36 -04:00
var dlg = dialogHelper.createDialog({
size: 'small',
removeOnClose: true,
autoFocus: false
});
2015-02-05 01:13:20 -05:00
2016-08-16 01:34:36 -04:00
dlg.classList.add('ui-body-a');
dlg.classList.add('background-theme-a');
dlg.classList.add('formDialog');
2016-01-30 15:59:09 -05:00
2016-08-16 01:34:36 -04:00
var html = '';
html += '<div class="formDialogHeader">';
html += '<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="md-icon">&#xE5C4;</i></button>';
html += '<div class="formDialogHeaderTitle">';
html += Globalize.translate('SyncMedia');
html += '</div>';
2015-12-14 10:43:03 -05:00
2016-08-16 01:34:36 -04:00
html += '<a href="https://github.com/MediaBrowser/Wiki/wiki/Sync" target="_blank" class="clearLink" style="margin-top:0;display:inline-block;vertical-align:middle;margin-left:auto;"><button is="emby-button" type="button" class="mini"><i class="md-icon">info</i><span>' + Globalize.translate('ButtonHelp') + '</span></button></a>';
2014-07-22 12:36:34 -04:00
2016-08-16 01:34:36 -04:00
html += '</div>';
2014-12-13 16:26:04 -05:00
2016-08-16 01:34:36 -04:00
html += '<div class="formDialogContent smoothScrollY" style="padding-top:2em;">';
html += '<div class="dialogContentInner dialog-content-centered">';
2016-08-07 02:15:03 -04:00
2016-08-16 01:34:36 -04:00
html += '<form class="formSubmitSyncRequest" style="margin: auto;">';
2016-02-10 21:56:24 -05:00
2016-08-16 01:34:36 -04:00
html += '<div class="formFields"></div>';
2014-07-22 12:36:34 -04:00
2016-08-16 01:34:36 -04:00
html += '<p>';
html += '<button is="emby-button" type="submit" class="raised submit block"><i class="md-icon">sync</i><span>' + Globalize.translate('ButtonSync') + '</span></button>';
html += '</p>';
2014-07-22 12:36:34 -04:00
2016-08-16 01:34:36 -04:00
html += '</form>';
2014-07-22 12:36:34 -04:00
2016-08-16 01:34:36 -04:00
html += '</div>';
html += '</div>';
2016-08-07 02:15:03 -04:00
2016-08-16 01:34:36 -04:00
dlg.innerHTML = html;
document.body.appendChild(dlg);
2016-08-18 01:56:10 -04:00
var submitted = false;
2014-07-22 12:36:34 -04:00
2016-08-16 01:34:36 -04:00
$('form', dlg).on('submit', function () {
2016-08-18 01:56:10 -04:00
submitted = submitJob(dlg, userId, options, this, dialogHelper);
2016-08-16 01:34:36 -04:00
return false;
});
2015-03-15 00:17:35 -04:00
2016-08-16 01:34:36 -04:00
$('.btnCancel', dlg).on('click', function () {
dialogHelper.close(dlg);
});
2015-12-14 10:43:03 -05:00
2016-08-16 01:34:36 -04:00
var promise = dialogHelper.open(dlg);
2015-12-14 10:43:03 -05:00
2016-08-16 01:34:36 -04:00
renderForm({
2016-08-16 14:54:08 -04:00
elem: dlg.querySelector('.formFields'),
2016-08-16 01:34:36 -04:00
dialogOptions: dialogOptions,
2016-08-23 01:08:07 -04:00
dialogOptionsFn: getTargetDialogOptionsFn(dialogOptionsQuery),
isLocalSync: options.isLocalSync
2015-03-15 00:17:35 -04:00
});
2015-06-18 02:23:44 -04:00
2016-08-18 01:56:10 -04:00
return promise.then(function () {
if (submitted) {
return Promise.resolve();
}
return Promise.reject();
});
2015-12-14 10:43:03 -05:00
});
2014-07-20 00:46:29 -04:00
}
2015-03-15 00:17:35 -04:00
function getTargetDialogOptionsFn(query) {
return function (targetId) {
query.TargetId = targetId;
return ApiClient.getJSON(ApiClient.getUrl('Sync/Options', query));
};
}
2016-02-17 23:57:19 -05:00
function setQualityFieldVisible(form, visible) {
if (visible) {
$('.fldQuality', form).show();
$('#selectQuality', form).attr('required', 'required');
} else {
$('.fldQuality', form).hide();
$('#selectQuality', form).removeAttr('required');
}
}
2015-03-15 00:17:35 -04:00
function onProfileChange(form, profileId) {
var options = currentDialogOptions || {};
var option = (options.ProfileOptions || []).filter(function (o) {
return o.Id == profileId;
})[0];
2016-04-16 00:35:09 -04:00
var qualityOptions = options.QualityOptions || [];
2015-03-15 00:17:35 -04:00
if (option) {
$('.profileDescription', form).html(option.Description || '');
2016-04-16 00:35:09 -04:00
setQualityFieldVisible(form, qualityOptions.length > 0 && option.EnableQualityOptions && options.Options.indexOf('Quality') != -1);
2015-03-15 00:17:35 -04:00
} else {
$('.profileDescription', form).html('');
2016-04-16 00:35:09 -04:00
setQualityFieldVisible(form, qualityOptions.length > 0 && options.Options.indexOf('Quality') != -1);
2015-03-15 00:17:35 -04:00
}
}
function onQualityChange(form, qualityId) {
2015-03-15 00:17:35 -04:00
var options = currentDialogOptions || {};
var option = (options.QualityOptions || []).filter(function (o) {
return o.Id == qualityId;
})[0];
2015-03-15 00:17:35 -04:00
if (option) {
$('.qualityDescription', form).html(option.Description || '');
} else {
$('.qualityDescription', form).html('');
}
2015-03-15 00:17:35 -04:00
if (qualityId == 'custom') {
$('.fldBitrate', form).show();
$('#txtBitrate', form).attr('required', 'required');
} else {
$('.fldBitrate', form).hide();
2015-03-15 15:10:27 -04:00
$('#txtBitrate', form).removeAttr('required').val('');
2015-03-15 00:17:35 -04:00
}
}
2015-03-15 00:17:35 -04:00
function renderTargetDialogOptions(form, options) {
currentDialogOptions = options;
2015-03-16 23:48:05 -04:00
if (options.ProfileOptions.length && options.Options.indexOf('Profile') != -1) {
2015-03-15 00:17:35 -04:00
$('.fldProfile', form).show();
$('#selectProfile', form).attr('required', 'required');
} else {
$('.fldProfile', form).hide();
$('#selectProfile', form).removeAttr('required');
}
setQualityFieldVisible(options.QualityOptions.length > 0);
$('#selectProfile', form).html(options.ProfileOptions.map(function (o) {
var selectedAttribute = o.IsDefault ? ' selected="selected"' : '';
return '<option value="' + o.Id + '"' + selectedAttribute + '>' + o.Name + '</option>';
2015-09-03 13:01:51 -04:00
}).join('')).trigger('change');
2015-03-15 00:17:35 -04:00
$('#selectQuality', form).html(options.QualityOptions.map(function (o) {
var selectedAttribute = o.IsDefault ? ' selected="selected"' : '';
return '<option value="' + o.Id + '"' + selectedAttribute + '>' + o.Name + '</option>';
2015-09-03 13:01:51 -04:00
}).join('')).trigger('change');
}
2016-02-17 23:57:19 -05:00
function loadQualityOptions(form, targetId, dialogOptionsFn) {
2015-10-05 22:50:20 -04:00
return dialogOptionsFn(targetId).then(function (options) {
2016-02-03 19:04:59 -05:00
return renderTargetDialogOptions(form, options);
2016-02-17 23:57:19 -05:00
});
}
2016-02-17 23:57:19 -05:00
return {
2014-07-20 00:46:29 -04:00
showMenu: showSyncMenu,
2015-03-15 15:10:27 -04:00
renderForm: renderForm,
setJobValues: setJobValues
};
2016-02-17 23:57:19 -05:00
});