mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
update sync
This commit is contained in:
parent
0a7858143c
commit
dd0540c6b9
13 changed files with 578 additions and 439 deletions
|
@ -14,12 +14,12 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
"ignore": [],
|
"ignore": [],
|
||||||
"version": "1.4.178",
|
"version": "1.4.180",
|
||||||
"_release": "1.4.178",
|
"_release": "1.4.180",
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "1.4.178",
|
"tag": "1.4.180",
|
||||||
"commit": "7c624942d8f173858375ee1b3dfe735a82245af6"
|
"commit": "053e9d6503c1b6322ce41ad044787990026d8e18"
|
||||||
},
|
},
|
||||||
"_source": "https://github.com/MediaBrowser/emby-webcomponents.git",
|
"_source": "https://github.com/MediaBrowser/emby-webcomponents.git",
|
||||||
"_target": "^1.2.1",
|
"_target": "^1.2.1",
|
||||||
|
|
|
@ -262,6 +262,11 @@ define(['dom'], function (dom) {
|
||||||
|
|
||||||
var elementRect = getViewportBoundingClientRect(curr, windowData);
|
var elementRect = getViewportBoundingClientRect(curr, windowData);
|
||||||
|
|
||||||
|
// not currently visible
|
||||||
|
if (!elementRect.width && !elementRect.height) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
|
|
|
@ -212,7 +212,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMobileApp && options.sync !== false) {
|
if (options.sync !== false) {
|
||||||
if (itemHelper.canSync(user, item)) {
|
if (itemHelper.canSync(user, item)) {
|
||||||
commands.push({
|
commands.push({
|
||||||
name: globalize.translate('sharedcomponents#SyncToOtherDevice'),
|
name: globalize.translate('sharedcomponents#SyncToOtherDevice'),
|
||||||
|
@ -428,7 +428,8 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
Id: itemId
|
Id: itemId
|
||||||
}]
|
}],
|
||||||
|
serverId: serverId
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
getResolveFunction(resolve, id)();
|
getResolveFunction(resolve, id)();
|
||||||
|
@ -442,7 +443,8 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'embyRouter',
|
||||||
{
|
{
|
||||||
Id: itemId
|
Id: itemId
|
||||||
}],
|
}],
|
||||||
isLocalSync: true
|
isLocalSync: true,
|
||||||
|
serverId: serverId
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
getResolveFunction(resolve, id)();
|
getResolveFunction(resolve, id)();
|
||||||
|
|
|
@ -259,15 +259,13 @@
|
||||||
|
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
name: globalize.translate('sharedcomponents#Refresh'),
|
name: globalize.translate('sharedcomponents#Refresh'),
|
||||||
id: 'refresh',
|
id: 'refresh'
|
||||||
ironIcon: 'refresh'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (user.Policy.EnableSync) {
|
if (user.Policy.EnableSync) {
|
||||||
menuItems.push({
|
menuItems.push({
|
||||||
name: globalize.translate('sharedcomponents#SyncToOtherDevice'),
|
name: globalize.translate('sharedcomponents#SyncToOtherDevice'),
|
||||||
id: 'sync',
|
id: 'sync'
|
||||||
ironIcon: 'sync'
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +343,8 @@
|
||||||
return {
|
return {
|
||||||
Id: i
|
Id: i
|
||||||
};
|
};
|
||||||
})
|
}),
|
||||||
|
serverId: serverId
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
hideSelections();
|
hideSelections();
|
||||||
|
@ -359,7 +358,8 @@
|
||||||
Id: i
|
Id: i
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
isLocalSync: true
|
isLocalSync: true,
|
||||||
|
serverId: serverId
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
hideSelections();
|
hideSelections();
|
||||||
|
|
|
@ -415,7 +415,7 @@ define(['browser', 'layoutManager', 'dom', 'scrollStyles'], function (browser, l
|
||||||
fill: 'both'
|
fill: 'both'
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!animation.immediate || browser.animate) {
|
if (browser.animate) {
|
||||||
animationConfig.easing = 'ease-out';
|
animationConfig.easing = 'ease-out';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -254,5 +254,21 @@
|
||||||
"ServerNameIsShuttingDown": "Emby Server - {0} is shutting down.",
|
"ServerNameIsShuttingDown": "Emby Server - {0} is shutting down.",
|
||||||
"HeaderDeleteItems": "Delete Items",
|
"HeaderDeleteItems": "Delete Items",
|
||||||
"ConfirmDeleteItems": "Deleting these items will delete them from both the file system and your media library. Are you sure you wish to continue?",
|
"ConfirmDeleteItems": "Deleting these items will delete them from both the file system and your media library. Are you sure you wish to continue?",
|
||||||
"PleaseRestartServerName": "Please restart Emby Server - {0}."
|
"PleaseRestartServerName": "Please restart Emby Server - {0}.",
|
||||||
|
"SyncJobCreated": "Sync job created.",
|
||||||
|
"LabelSyncTo": "Sync to:",
|
||||||
|
"LabelSyncJobName": "Sync job name:",
|
||||||
|
"LabelQuality": "Quality:",
|
||||||
|
"LabelSyncNoTargetsHelp": "It looks like you don't currently have any apps that support sync.",
|
||||||
|
"DownloadScheduled": "Download scheduled",
|
||||||
|
"LearnMore": "Learn more",
|
||||||
|
"LabelProfile": "Profile:",
|
||||||
|
"LabelBitrateMbps": "Bitrate (Mbps):",
|
||||||
|
"SyncUnwatchedVideosOnly": "Sync unwatched videos only",
|
||||||
|
"SyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched.",
|
||||||
|
"AutomaticallySyncNewContent": "Automatically sync new content",
|
||||||
|
"AutomaticallySyncNewContentHelp": "New content added to this folder will be automatically synced to the device.",
|
||||||
|
"LabelItemLimit": "Item limit:",
|
||||||
|
"LabelItemLimitHelp": "Optional. Set a limit to the number of items that will be synced.",
|
||||||
|
"PleaseSelectDeviceToSyncTo": "Please select a device to sync to."
|
||||||
}
|
}
|
526
dashboard-ui/bower_components/emby-webcomponents/sync/sync.js
vendored
Normal file
526
dashboard-ui/bower_components/emby-webcomponents/sync/sync.js
vendored
Normal file
|
@ -0,0 +1,526 @@
|
||||||
|
define(['apphost', 'globalize', 'connectionManager', 'layoutManager', 'shell', 'focusManager', 'scrollHelper', 'paper-icon-button-light', 'formDialogStyle'], function (appHost, globalize, connectionManager, layoutManager, shell, focusManager, scrollHelper) {
|
||||||
|
|
||||||
|
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 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 += '<div class="inputContainer' + targetContainerClass + '">';
|
||||||
|
html += '<input is="emby-input" type="text" id="txtSyncJobName" class="txtSyncJobName" required="required" label="' + globalize.translate('sharedcomponents#LabelSyncJobName') + '"/>';
|
||||||
|
html += '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.readOnlySyncTarget) {
|
||||||
|
html += '<div class="inputContainer' + targetContainerClass + '">';
|
||||||
|
html += '<input is="emby-input" type="text" id="selectSyncTarget" readonly label="' + globalize.translate('sharedcomponents#LabelSyncTo') + '"/>';
|
||||||
|
html += '</div>';
|
||||||
|
} else {
|
||||||
|
html += '<div class="selectContainer' + targetContainerClass + '">';
|
||||||
|
html += '<select is="emby-select" id="selectSyncTarget" required="required" label="' + globalize.translate('sharedcomponents#LabelSyncTo') + '">';
|
||||||
|
|
||||||
|
html += targets.map(function (t) {
|
||||||
|
|
||||||
|
var isSelected = t.Id == appInfo.deviceId;
|
||||||
|
var selectedHtml = isSelected ? ' selected="selected"' : '';
|
||||||
|
return '<option' + selectedHtml + ' value="' + t.Id + '">' + t.Name + '</option>';
|
||||||
|
|
||||||
|
}).join('');
|
||||||
|
html += '</select>';
|
||||||
|
if (!targets.length) {
|
||||||
|
html += '<div class="fieldDescription">' + globalize.translate('sharedcomponents#LabelSyncNoTargetsHelp') + '</div>';
|
||||||
|
html += '<div class="fieldDescription"><a class="lnkHelp" href="https://github.com/MediaBrowser/Wiki/wiki/Sync" target="_blank">' + globalize.translate('sharedcomponents#LearnMore') + '</a></div>';
|
||||||
|
}
|
||||||
|
html += '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '<div class="fldProfile selectContainer hide">';
|
||||||
|
html += '<select is="emby-select" id="selectProfile" label="' + globalize.translate('sharedcomponents#LabelProfile') + '">';
|
||||||
|
html += '</select>';
|
||||||
|
html += '<div class="fieldDescription profileDescription"></div>';
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
html += '<div class="fldQuality selectContainer hide">';
|
||||||
|
html += '<select is="emby-select" id="selectQuality" data-mini="true" required="required" label="' + globalize.translate('sharedcomponents#LabelQuality') + '">';
|
||||||
|
html += '</select>';
|
||||||
|
html += '<div class="fieldDescription qualityDescription"></div>';
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
html += '<div class="fldBitrate inputContainer hide">';
|
||||||
|
html += '<input is="emby-input" type="number" step=".1" min=".1" id="txtBitrate" label="' + globalize.translate('sharedcomponents#LabelBitrateMbps') + '"/>';
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
if (dialogOptions.Options.indexOf('UnwatchedOnly') != -1) {
|
||||||
|
html += '<div class="checkboxContainer checkboxContainer-withDescription">';
|
||||||
|
html += '<label>';
|
||||||
|
html += '<input is="emby-checkbox" type="checkbox" id="chkUnwatchedOnly"/>';
|
||||||
|
html += '<span>' + globalize.translate('sharedcomponents#SyncUnwatchedVideosOnly') + '</span>';
|
||||||
|
html += '</label>';
|
||||||
|
html += '<div class="fieldDescription checkboxFieldDescription">' + globalize.translate('sharedcomponents#SyncUnwatchedVideosOnlyHelp') + '</div>';
|
||||||
|
html += '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
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('sharedcomponents#AutomaticallySyncNewContent') + '</span>';
|
||||||
|
html += '</label>';
|
||||||
|
html += '<div class="fieldDescription checkboxFieldDescription">' + globalize.translate('sharedcomponents#AutomaticallySyncNewContentHelp') + '</div>';
|
||||||
|
html += '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
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('sharedcomponents#LabelItemLimit') + '"/>';
|
||||||
|
html += '<div class="fieldDescription">' + globalize.translate('sharedcomponents#LabelItemLimitHelp') + '</div>';
|
||||||
|
html += '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
//html += '</div>';
|
||||||
|
//html += '</div>';
|
||||||
|
|
||||||
|
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 lnkHelp = elem.querySelector('.lnkHelp');
|
||||||
|
if (lnkHelp) {
|
||||||
|
lnkHelp.addEventListener('click', onHelpLinkClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
focusManager.autoFocus(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 showSyncMenuInternal(dialogHelper, options) {
|
||||||
|
|
||||||
|
var apiClient = connectionManager.getApiClient(options.serverId);
|
||||||
|
|
||||||
|
var userId = apiClient.getCurrentUserId();
|
||||||
|
|
||||||
|
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 += '<div class="formDialogHeader">';
|
||||||
|
html += '<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="md-icon"></i></button>';
|
||||||
|
html += '<div class="formDialogHeaderTitle">';
|
||||||
|
html += globalize.translate('sharedcomponents#Sync');
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
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('sharedcomponents#ButtonHelp') + '</span></button></a>';
|
||||||
|
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
html += '<div class="formDialogContent smoothScrollY" style="padding-top:2em;">';
|
||||||
|
html += '<div class="dialogContentInner dialog-content-centered">';
|
||||||
|
|
||||||
|
html += '<form class="formSubmitSyncRequest" style="margin: auto;">';
|
||||||
|
|
||||||
|
html += '<div class="formFields"></div>';
|
||||||
|
|
||||||
|
html += '<p>';
|
||||||
|
html += '<button is="emby-button" type="submit" class="raised submit block"><i class="md-icon">sync</i><span>' + globalize.translate('sharedcomponents#Sync') + '</span></button>';
|
||||||
|
html += '</p>';
|
||||||
|
|
||||||
|
html += '</form>';
|
||||||
|
|
||||||
|
html += '</div>';
|
||||||
|
html += '</div>';
|
||||||
|
|
||||||
|
|
||||||
|
dlg.innerHTML = html;
|
||||||
|
document.body.appendChild(dlg);
|
||||||
|
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 '<option value="' + o.Id + '"' + selectedAttribute + '>' + o.Name + '</option>';
|
||||||
|
|
||||||
|
}).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 '<option value="' + o.Id + '"' + selectedAttribute + '>' + o.Name + '</option>';
|
||||||
|
|
||||||
|
}).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
|
||||||
|
};
|
||||||
|
});
|
|
@ -26,14 +26,14 @@
|
||||||
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
|
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
|
||||||
},
|
},
|
||||||
"main": "iron-meta.html",
|
"main": "iron-meta.html",
|
||||||
"homepage": "https://github.com/polymerelements/iron-meta",
|
"homepage": "https://github.com/PolymerElements/iron-meta",
|
||||||
"_release": "1.1.1",
|
"_release": "1.1.1",
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "v1.1.1",
|
"tag": "v1.1.1",
|
||||||
"commit": "e171ee234b482219c9514e6f9551df48ef48bd9f"
|
"commit": "e171ee234b482219c9514e6f9551df48ef48bd9f"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/polymerelements/iron-meta.git",
|
"_source": "git://github.com/PolymerElements/iron-meta.git",
|
||||||
"_target": "^1.0.0",
|
"_target": "^1.0.0",
|
||||||
"_originalSource": "polymerelements/iron-meta"
|
"_originalSource": "PolymerElements/iron-meta"
|
||||||
}
|
}
|
|
@ -32,14 +32,14 @@
|
||||||
"iron-component-page": "polymerElements/iron-component-page#^1.1.6"
|
"iron-component-page": "polymerElements/iron-component-page#^1.1.6"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://github.com/Polymer/polymer",
|
"homepage": "https://github.com/polymer/polymer",
|
||||||
"_release": "1.6.1",
|
"_release": "1.6.1",
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "v1.6.1",
|
"tag": "v1.6.1",
|
||||||
"commit": "1f197d9d7874b1e5808b2a5c26f34446a7d912fc"
|
"commit": "1f197d9d7874b1e5808b2a5c26f34446a7d912fc"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/Polymer/polymer.git",
|
"_source": "git://github.com/polymer/polymer.git",
|
||||||
"_target": "^1.1.0",
|
"_target": "^1.1.0",
|
||||||
"_originalSource": "Polymer/polymer"
|
"_originalSource": "polymer/polymer"
|
||||||
}
|
}
|
|
@ -35,7 +35,8 @@
|
||||||
require(['syncDialog'], function (syncDialog) {
|
require(['syncDialog'], function (syncDialog) {
|
||||||
syncDialog.showMenu({
|
syncDialog.showMenu({
|
||||||
ParentId: parentId,
|
ParentId: parentId,
|
||||||
Category: category
|
Category: category,
|
||||||
|
serverId: ApiClient.serverId()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2041,7 +2041,8 @@
|
||||||
function onSyncClick() {
|
function onSyncClick() {
|
||||||
require(['syncDialog'], function (syncDialog) {
|
require(['syncDialog'], function (syncDialog) {
|
||||||
syncDialog.showMenu({
|
syncDialog.showMenu({
|
||||||
items: [currentItem]
|
items: [currentItem],
|
||||||
|
serverId: ApiClient.serverId()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2058,7 +2059,9 @@
|
||||||
require(['syncDialog'], function (syncDialog) {
|
require(['syncDialog'], function (syncDialog) {
|
||||||
syncDialog.showMenu({
|
syncDialog.showMenu({
|
||||||
items: [currentItem],
|
items: [currentItem],
|
||||||
isLocalSync: true
|
isLocalSync: true,
|
||||||
|
serverId: ApiClient.serverId()
|
||||||
|
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
reload(view, params);
|
reload(view, params);
|
||||||
}, resetSyncStatus);
|
}, resetSyncStatus);
|
||||||
|
|
|
@ -1320,6 +1320,7 @@ var AppInfo = {};
|
||||||
define("chaptercardbuilder", [embyWebComponentsBowerPath + "/cardbuilder/chaptercardbuilder"], returnFirstDependency);
|
define("chaptercardbuilder", [embyWebComponentsBowerPath + "/cardbuilder/chaptercardbuilder"], returnFirstDependency);
|
||||||
|
|
||||||
define("tvguide", [embyWebComponentsBowerPath + "/guide/guide", 'embyRouter'], returnFirstDependency);
|
define("tvguide", [embyWebComponentsBowerPath + "/guide/guide", 'embyRouter'], returnFirstDependency);
|
||||||
|
define("syncDialog", [embyWebComponentsBowerPath + "/sync/sync"], returnFirstDependency);
|
||||||
define("voiceDialog", [embyWebComponentsBowerPath + "/voice/voicedialog"], returnFirstDependency);
|
define("voiceDialog", [embyWebComponentsBowerPath + "/voice/voicedialog"], returnFirstDependency);
|
||||||
define("voiceReceiver", [embyWebComponentsBowerPath + "/voice/voicereceiver"], returnFirstDependency);
|
define("voiceReceiver", [embyWebComponentsBowerPath + "/voice/voicereceiver"], returnFirstDependency);
|
||||||
define("voiceProcessor", [embyWebComponentsBowerPath + "/voice/voiceprocessor"], returnFirstDependency);
|
define("voiceProcessor", [embyWebComponentsBowerPath + "/voice/voiceprocessor"], returnFirstDependency);
|
||||||
|
@ -1352,8 +1353,6 @@ var AppInfo = {};
|
||||||
paths.appStorage = getAppStorage(apiClientBowerPath);
|
paths.appStorage = getAppStorage(apiClientBowerPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
paths.syncDialog = "scripts/sync";
|
|
||||||
|
|
||||||
var sha1Path = bowerPath + "/cryptojslib/components/sha1-min";
|
var sha1Path = bowerPath + "/cryptojslib/components/sha1-min";
|
||||||
var md5Path = bowerPath + "/cryptojslib/components/md5-min";
|
var md5Path = bowerPath + "/cryptojslib/components/md5-min";
|
||||||
var shim = {};
|
var shim = {};
|
||||||
|
|
|
@ -1,413 +0,0 @@
|
||||||
define(['apphost', 'jQuery', 'paper-icon-button-light'], function (appHost, $) {
|
|
||||||
|
|
||||||
var currentDialogOptions;
|
|
||||||
|
|
||||||
function submitJob(dlg, 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 target = $('#selectSyncTarget', form).val();
|
|
||||||
|
|
||||||
if (!target) {
|
|
||||||
|
|
||||||
require(['toast'], function (toast) {
|
|
||||||
toast(Globalize.translate('MessagePleaseSelectDeviceToSyncTo'));
|
|
||||||
});
|
|
||||||
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('MessageDownloadScheduled') : Globalize.translate('MessageSyncJobCreated');
|
|
||||||
|
|
||||||
toast(msg);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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 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 += '<div class="inputContainer' + targetContainerClass + '">';
|
|
||||||
html += '<input is="emby-input" type="text" id="txtSyncJobName" class="txtSyncJobName" required="required" label="' + Globalize.translate('LabelSyncJobName') + '"/>';
|
|
||||||
html += '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.readOnlySyncTarget) {
|
|
||||||
html += '<div class="inputContainer' + targetContainerClass + '">';
|
|
||||||
html += '<input is="emby-input" type="text" id="selectSyncTarget" readonly label="' + Globalize.translate('LabelSyncTo') + '"/>';
|
|
||||||
html += '</div>';
|
|
||||||
} else {
|
|
||||||
html += '<div class="selectContainer' + targetContainerClass + '">';
|
|
||||||
html += '<select is="emby-select" id="selectSyncTarget" required="required" label="' + Globalize.translate('LabelSyncTo') + '">';
|
|
||||||
|
|
||||||
html += targets.map(function (t) {
|
|
||||||
|
|
||||||
var isSelected = t.Id == appInfo.deviceId;
|
|
||||||
var selectedHtml = isSelected ? ' selected="selected"' : '';
|
|
||||||
return '<option' + selectedHtml + ' value="' + t.Id + '">' + t.Name + '</option>';
|
|
||||||
|
|
||||||
}).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>';
|
|
||||||
}
|
|
||||||
html += '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
html += '<div class="fldProfile selectContainer" style="display:none;">';
|
|
||||||
html += '<select is="emby-select" id="selectProfile" label="' + Globalize.translate('LabelProfile') + '">';
|
|
||||||
html += '</select>';
|
|
||||||
html += '<div class="fieldDescription profileDescription"></div>';
|
|
||||||
html += '</div>';
|
|
||||||
|
|
||||||
html += '<div class="fldQuality selectContainer" style="display:none;">';
|
|
||||||
html += '<select is="emby-select" id="selectQuality" data-mini="true" required="required" label="' + Globalize.translate('LabelQuality') + '">';
|
|
||||||
html += '</select>';
|
|
||||||
html += '<div class="fieldDescription qualityDescription"></div>';
|
|
||||||
html += '</div>';
|
|
||||||
|
|
||||||
html += '<div class="fldBitrate inputContainer" style="display:none;">';
|
|
||||||
html += '<input is="emby-input" type="number" step=".1" min=".1" id="txtBitrate" label="' + Globalize.translate('LabelBitrateMbps') + '"/>';
|
|
||||||
html += '</div>';
|
|
||||||
|
|
||||||
if (dialogOptions.Options.indexOf('UnwatchedOnly') != -1) {
|
|
||||||
html += '<div class="checkboxContainer checkboxContainer-withDescription">';
|
|
||||||
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>';
|
|
||||||
html += '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
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>';
|
|
||||||
html += '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
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>';
|
|
||||||
html += '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
//html += '</div>';
|
|
||||||
//html += '</div>';
|
|
||||||
|
|
||||||
elem.innerHTML = html;
|
|
||||||
|
|
||||||
$('#selectSyncTarget', elem).on('change', function () {
|
|
||||||
|
|
||||||
loadQualityOptions(elem, this.value, options.dialogOptionsFn).then(resolve);
|
|
||||||
|
|
||||||
}).trigger('change');
|
|
||||||
|
|
||||||
$('#selectProfile', elem).on('change', function () {
|
|
||||||
|
|
||||||
onProfileChange(elem, this.value);
|
|
||||||
|
|
||||||
}).trigger('change');
|
|
||||||
|
|
||||||
$('#selectQuality', elem).on('change', function () {
|
|
||||||
|
|
||||||
onQualityChange(elem, this.value);
|
|
||||||
|
|
||||||
}).trigger('change');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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 showSyncMenuInternal(dialogHelper, options) {
|
|
||||||
|
|
||||||
var userId = Dashboard.getCurrentUserId();
|
|
||||||
|
|
||||||
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 dlg = dialogHelper.createDialog({
|
|
||||||
size: 'small',
|
|
||||||
removeOnClose: true,
|
|
||||||
autoFocus: false
|
|
||||||
});
|
|
||||||
|
|
||||||
dlg.classList.add('ui-body-a');
|
|
||||||
dlg.classList.add('background-theme-a');
|
|
||||||
dlg.classList.add('formDialog');
|
|
||||||
|
|
||||||
var html = '';
|
|
||||||
html += '<div class="formDialogHeader">';
|
|
||||||
html += '<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"><i class="md-icon"></i></button>';
|
|
||||||
html += '<div class="formDialogHeaderTitle">';
|
|
||||||
html += Globalize.translate('SyncMedia');
|
|
||||||
html += '</div>';
|
|
||||||
|
|
||||||
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>';
|
|
||||||
|
|
||||||
html += '</div>';
|
|
||||||
|
|
||||||
html += '<div class="formDialogContent smoothScrollY" style="padding-top:2em;">';
|
|
||||||
html += '<div class="dialogContentInner dialog-content-centered">';
|
|
||||||
|
|
||||||
html += '<form class="formSubmitSyncRequest" style="margin: auto;">';
|
|
||||||
|
|
||||||
html += '<div class="formFields"></div>';
|
|
||||||
|
|
||||||
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>';
|
|
||||||
|
|
||||||
html += '</form>';
|
|
||||||
|
|
||||||
html += '</div>';
|
|
||||||
html += '</div>';
|
|
||||||
|
|
||||||
|
|
||||||
dlg.innerHTML = html;
|
|
||||||
document.body.appendChild(dlg);
|
|
||||||
var submitted = false;
|
|
||||||
|
|
||||||
$('form', dlg).on('submit', function () {
|
|
||||||
|
|
||||||
submitted = submitJob(dlg, userId, options, this, dialogHelper);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.btnCancel', dlg).on('click', function () {
|
|
||||||
dialogHelper.close(dlg);
|
|
||||||
});
|
|
||||||
|
|
||||||
var promise = dialogHelper.open(dlg);
|
|
||||||
|
|
||||||
renderForm({
|
|
||||||
elem: dlg.querySelector('.formFields'),
|
|
||||||
dialogOptions: dialogOptions,
|
|
||||||
dialogOptionsFn: getTargetDialogOptionsFn(dialogOptionsQuery),
|
|
||||||
isLocalSync: options.isLocalSync
|
|
||||||
});
|
|
||||||
|
|
||||||
return promise.then(function () {
|
|
||||||
if (submitted) {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
return Promise.reject();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTargetDialogOptionsFn(query) {
|
|
||||||
|
|
||||||
return function (targetId) {
|
|
||||||
|
|
||||||
query.TargetId = targetId;
|
|
||||||
return ApiClient.getJSON(ApiClient.getUrl('Sync/Options', query));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function setQualityFieldVisible(form, visible) {
|
|
||||||
|
|
||||||
if (visible) {
|
|
||||||
$('.fldQuality', form).show();
|
|
||||||
$('#selectQuality', form).attr('required', 'required');
|
|
||||||
} else {
|
|
||||||
$('.fldQuality', form).hide();
|
|
||||||
$('#selectQuality', form).removeAttr('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) {
|
|
||||||
$('.profileDescription', form).html(option.Description || '');
|
|
||||||
setQualityFieldVisible(form, qualityOptions.length > 0 && option.EnableQualityOptions && options.Options.indexOf('Quality') != -1);
|
|
||||||
} else {
|
|
||||||
$('.profileDescription', form).html('');
|
|
||||||
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];
|
|
||||||
|
|
||||||
if (option) {
|
|
||||||
$('.qualityDescription', form).html(option.Description || '');
|
|
||||||
} else {
|
|
||||||
$('.qualityDescription', form).html('');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qualityId == 'custom') {
|
|
||||||
$('.fldBitrate', form).show();
|
|
||||||
$('#txtBitrate', form).attr('required', 'required');
|
|
||||||
} else {
|
|
||||||
$('.fldBitrate', form).hide();
|
|
||||||
$('#txtBitrate', form).removeAttr('required').val('');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderTargetDialogOptions(form, options) {
|
|
||||||
|
|
||||||
currentDialogOptions = options;
|
|
||||||
|
|
||||||
if (options.ProfileOptions.length && options.Options.indexOf('Profile') != -1) {
|
|
||||||
$('.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>';
|
|
||||||
|
|
||||||
}).join('')).trigger('change');
|
|
||||||
|
|
||||||
$('#selectQuality', form).html(options.QualityOptions.map(function (o) {
|
|
||||||
|
|
||||||
var selectedAttribute = o.IsDefault ? ' selected="selected"' : '';
|
|
||||||
return '<option value="' + o.Id + '"' + selectedAttribute + '>' + o.Name + '</option>';
|
|
||||||
|
|
||||||
}).join('')).trigger('change');
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadQualityOptions(form, targetId, dialogOptionsFn) {
|
|
||||||
|
|
||||||
return dialogOptionsFn(targetId).then(function (options) {
|
|
||||||
|
|
||||||
return renderTargetDialogOptions(form, options);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
|
|
||||||
showMenu: showSyncMenu,
|
|
||||||
renderForm: renderForm,
|
|
||||||
setJobValues: setJobValues
|
|
||||||
};
|
|
||||||
});
|
|
Loading…
Add table
Add a link
Reference in a new issue