Merge pull request #202 from dkanada/sync

remove sync and registration services
This commit is contained in:
Joshua M. Boniface 2019-03-21 09:06:14 -04:00 committed by GitHub
commit 37cb47aea5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 103 additions and 1558 deletions

View File

@ -1,31 +0,0 @@
define(["itemHelper", "libraryMenu", "apphost"], function(itemHelper, libraryMenu, appHost) {
"use strict";
function initSyncButtons(view) {
var apiClient = window.ApiClient;
apiClient && apiClient.getCurrentUserId() && apiClient.getCurrentUser().then(function(user) {
for (var item = {
SupportsSync: !0
}, categorySyncButtons = view.querySelectorAll(".categorySyncButton"), i = 0, length = categorySyncButtons.length; i < length; i++) categorySyncButtons[i].addEventListener("click", onCategorySyncButtonClick), itemHelper.canSync(user, item) ? categorySyncButtons[i].classList.remove("hide") : categorySyncButtons[i].classList.add("hide")
})
}
function onCategorySyncButtonClick(e) {
var button = this,
category = button.getAttribute("data-category"),
parentId = libraryMenu.getTopParentId();
require(["syncDialog"], function(syncDialog) {
syncDialog.showMenu({
ParentId: parentId,
Category: category,
serverId: ApiClient.serverId(),
mode: appHost.supports("sync") ? "download" : "sync"
})
})
}
return {
init: function(view) {
initSyncButtons(view)
}
}
});

View File

@ -4,25 +4,11 @@ define(['browser', 'dom', 'layoutManager', 'shell', 'appRouter', 'apphost', 'css
var EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype);
var EmbyLinkButtonPrototype = Object.create(HTMLAnchorElement.prototype);
function openPremiumInfo() {
require(['registrationServices'], function (registrationServices) {
registrationServices.showPremiereInfo();
});
}
function onAnchorClick(e) {
var href = this.getAttribute('href') || '';
if (href !== '#') {
if (this.getAttribute('target')) {
if (href.indexOf('emby.media/premiere') !== -1 && !appHost.supports('externalpremium')) {
e.preventDefault();
openPremiumInfo();
}
else if (!appHost.supports('targetblank')) {
if (!appHost.supports('targetblank')) {
e.preventDefault();
shell.openUrl(href);
}

View File

@ -1,4 +1,4 @@
define(['connectionManager', 'cardBuilder', 'registrationServices', 'appSettings', 'dom', 'apphost', 'layoutManager', 'imageLoader', 'globalize', 'itemShortcuts', 'itemHelper', 'appRouter', 'emby-button', 'paper-icon-button-light', 'emby-itemscontainer', 'emby-scroller', 'emby-linkbutton', 'css!./homesections'], function (connectionManager, cardBuilder, registrationServices, appSettings, dom, appHost, layoutManager, imageLoader, globalize, itemShortcuts, itemHelper, appRouter) {
define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'layoutManager', 'imageLoader', 'globalize', 'itemShortcuts', 'itemHelper', 'appRouter', 'emby-button', 'paper-icon-button-light', 'emby-itemscontainer', 'emby-scroller', 'emby-linkbutton', 'css!./homesections'], function (connectionManager, cardBuilder, appSettings, dom, appHost, layoutManager, imageLoader, globalize, itemShortcuts, itemHelper, appRouter) {
'use strict';
function getDefaultSection(index) {
@ -662,34 +662,10 @@ define(['connectionManager', 'cardBuilder', 'registrationServices', 'appSettings
itemsContainer.parentContainer = elem;
}
function bindUnlockClick(elem) {
var btnUnlock = elem.querySelector('.btnUnlock');
if (btnUnlock) {
btnUnlock.addEventListener('click', function (e) {
registrationServices.validateFeature('livetv', {
viewOnly: true
}).then(function () {
dom.parentWithClass(elem, 'homeSectionsContainer').dispatchEvent(new CustomEvent('settingschange', {
cancelable: false
}));
});
});
}
}
function getOnNowFetchFn(serverId) {
return function () {
var apiClient = connectionManager.getApiClient(serverId);
return apiClient.getLiveTvRecommendedPrograms({
userId: apiClient.getCurrentUserId(),
IsAiring: true,
limit: 24,
@ -697,15 +673,12 @@ define(['connectionManager', 'cardBuilder', 'registrationServices', 'appSettings
EnableImageTypes: "Primary,Thumb,Backdrop",
EnableTotalRecordCount: false,
Fields: "ChannelInfo,PrimaryImageAspectRatio"
});
};
}
function getOnNowItemsHtml(items) {
var cardLayout = false;
return cardBuilder.getCardsHtml({
items: items,
preferThumb: 'auto',
@ -728,27 +701,12 @@ define(['connectionManager', 'cardBuilder', 'registrationServices', 'appSettings
}
function loadOnNow(elem, apiClient, user) {
if (!user.Policy.EnableLiveTvAccess) {
return Promise.resolve();
}
var promises = [];
promises.push(registrationServices.validateFeature('livetv',
{
viewOnly: true,
showDialog: false
}).then(function () {
return true;
}, function () {
return false;
}));
var userId = user.Id;
promises.push(apiClient.getLiveTvRecommendedPrograms({
apiClient.getLiveTvRecommendedPrograms({
userId: apiClient.getCurrentUserId(),
IsAiring: true,
limit: 1,
@ -756,17 +714,9 @@ define(['connectionManager', 'cardBuilder', 'registrationServices', 'appSettings
EnableImageTypes: "Primary,Thumb,Backdrop",
EnableTotalRecordCount: false,
Fields: "ChannelInfo,PrimaryImageAspectRatio"
}));
return Promise.all(promises).then(function (responses) {
var registered = responses[0];
var result = responses[1];
}).then(function (result) {
var html = '';
if (result.Items.length && registered) {
if (result.Items.length) {
elem.classList.remove('padded-left');
elem.classList.remove('padded-right');
elem.classList.remove('padded-bottom');
@ -774,51 +724,38 @@ define(['connectionManager', 'cardBuilder', 'registrationServices', 'appSettings
html += '<div class="verticalSection">';
html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">';
html += '<h2 class="sectionTitle sectionTitle-cards">' + globalize.translate('LiveTV') + '</h2>';
html += '</div>';
if (enableScrollX()) {
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true" data-scrollbuttons="false">';
html += '<div class="scrollSlider padded-left padded-right padded-top padded-bottom focuscontainer-x">';
}
else {
} else {
html += '<div class="padded-left padded-right padded-top focuscontainer-x">';
}
html += '<a style="margin-left:.8em;margin-right:0;" is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', {
serverId: apiClient.serverId()
}) + '" class="raised"><span>' + globalize.translate('Programs') + '</span></a>';
html += '<a style="margin-left:.5em;margin-right:0;" is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', {
serverId: apiClient.serverId(),
section: 'guide'
}) + '" class="raised"><span>' + globalize.translate('Guide') + '</span></a>';
html += '<a style="margin-left:.5em;margin-right:0;" is="emby-linkbutton" href="' + appRouter.getRouteUrl('recordedtv', {
serverId: apiClient.serverId()
}) + '" class="raised"><span>' + globalize.translate('Recordings') + '</span></a>';
html += '<a style="margin-left:.5em;margin-right:0;" is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', {
serverId: apiClient.serverId(),
section: 'dvrschedule'
}) + '" class="raised"><span>' + globalize.translate('Schedule') + '</span></a>';
html += '</div>';
if (enableScrollX()) {
html += '</div>';
}
html += '</div>';
html += '</div>';
@ -826,12 +763,9 @@ define(['connectionManager', 'cardBuilder', 'registrationServices', 'appSettings
html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">';
if (!layoutManager.tv) {
html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', {
serverId: apiClient.serverId(),
section: 'onnow'
}) + '" class="more button-flat button-flat-mini sectionTitleTextButton">';
html += '<h2 class="sectionTitle sectionTitle-cards">';
html += globalize.translate('HeaderOnNow');
@ -863,22 +797,7 @@ define(['connectionManager', 'cardBuilder', 'registrationServices', 'appSettings
itemsContainer.parentContainer = elem;
itemsContainer.fetchData = getOnNowFetchFn(apiClient.serverId());
itemsContainer.getItemsHtml = getOnNowItemsHtml;
} else if (result.Items.length && !registered) {
elem.classList.add('padded-left');
elem.classList.add('padded-right');
elem.classList.add('padded-bottom');
html += '<h2 class="sectionTitle">' + globalize.translate('LiveTvRequiresUnlock') + '</h2>';
html += '<button is="emby-button" type="button" class="raised button-submit block btnUnlock">';
html += '<span>' + globalize.translate('HeaderBecomeProjectSupporter') + '</span>';
html += '</button>';
elem.innerHTML = html;
}
bindUnlockClick(elem);
});
}

View File

@ -118,13 +118,6 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
});
}
if (itemHelper.canConvert(item, user, connectionManager.getApiClient(item))) {
commands.push({
name: globalize.translate('Convert'),
id: 'convert'
});
}
if (item.CanDelete && options.deleteItem !== false) {
if (item.Type === 'Playlist' || item.Type === 'BoxSet') {
@ -147,15 +140,6 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
});
}
if (appHost.supports('sync') && options.syncLocal !== false) {
if (itemHelper.canSync(user, item)) {
commands.push({
name: globalize.translate('Download'),
id: 'synclocal'
});
}
}
var canEdit = itemHelper.canEdit(user, item);
if (canEdit) {
@ -328,17 +312,13 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
{
require(['fileDownloader'], function (fileDownloader) {
var downloadHref = apiClient.getItemDownloadUrl(itemId);
fileDownloader.download([
{
fileDownloader.download([{
url: downloadHref,
itemId: itemId,
serverId: serverId
}]);
getResolveFunction(getResolveFunction(resolve, id), id)();
});
break;
}
case 'editsubtitles':
@ -433,102 +413,48 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
break;
}
case 'share':
{
navigator.share({
title: item.Name,
text: item.Overview,
url: "https://github.com/jellyfin/jellyfin"
});
break;
}
case 'album':
{
appRouter.showItem(item.AlbumId, item.ServerId);
getResolveFunction(resolve, id)();
break;
}
case 'artist':
{
appRouter.showItem(item.ArtistItems[0].Id, item.ServerId);
getResolveFunction(resolve, id)();
break;
}
case 'playallfromhere':
{
getResolveFunction(resolve, id)();
break;
}
case 'queueallfromhere':
{
getResolveFunction(resolve, id)();
break;
}
case 'convert':
{
require(['syncDialog'], function (syncDialog) {
syncDialog.showMenu({
items: [item],
serverId: serverId,
mode: 'convert'
});
});
getResolveFunction(resolve, id)();
break;
}
case 'sync':
{
require(['syncDialog'], function (syncDialog) {
syncDialog.showMenu({
items: [item],
serverId: serverId,
mode: 'sync'
});
});
getResolveFunction(resolve, id)();
break;
}
case 'synclocal':
{
require(['syncDialog'], function (syncDialog) {
syncDialog.showMenu({
items: [item],
serverId: serverId,
mode: 'download'
});
});
getResolveFunction(resolve, id)();
break;
}
case 'removefromplaylist':
apiClient.ajax({
url: apiClient.getUrl('Playlists/' + options.playlistId + '/Items', {
EntryIds: [item.PlaylistItemId].join(',')
}),
type: 'DELETE'
}).then(function () {
getResolveFunction(resolve, id, true)();
});
break;
case 'removefromcollection':
apiClient.ajax({
type: "DELETE",
url: apiClient.getUrl("Collections/" + options.collectionId + "/Items", {
Ids: [item.Id].join(',')
})
}).then(function () {
getResolveFunction(resolve, id, true)();
});
break;
case 'canceltimer':
deleteTimer(apiClient, item, resolve, id);

View File

@ -218,13 +218,6 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo
});
}
if (user.Policy.EnableContentDownloading && appHost.supports('sync')) {
menuItems.push({
name: globalize.translate('Download'),
id: 'synclocal'
});
}
menuItems.push({
name: globalize.translate('GroupVersions'),
id: 'groupvideos',
@ -254,20 +247,16 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo
}
require(['actionsheet'], function (actionsheet) {
actionsheet.show({
items: menuItems,
positionTo: e.target,
callback: function (id) {
var items = selectedItems.slice(0);
var serverId = apiClient.serverInfo().Id;
switch (id) {
case 'addtocollection':
require(['collectionEditor'], function (collectionEditor) {
new collectionEditor().show({
items: items,
serverId: serverId
@ -318,35 +307,6 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo
hideSelections();
dispatchNeedsRefresh();
break;
case 'sync':
require(['syncDialog'], function (syncDialog) {
syncDialog.showMenu({
items: items.map(function (i) {
return {
Id: i
};
}),
serverId: serverId
});
});
hideSelections();
dispatchNeedsRefresh();
break;
case 'synclocal':
require(['syncDialog'], function (syncDialog) {
syncDialog.showMenu({
items: items.map(function (i) {
return {
Id: i
};
}),
isLocalSync: true,
serverId: serverId
});
});
hideSelections();
dispatchNeedsRefresh();
break;
default:
break;
}

View File

@ -2,16 +2,13 @@ define(['connectionManager', 'globalize'], function (connectionManager, globaliz
"use strict";
function getRequirePromise(deps) {
return new Promise(function (resolve, reject) {
require(deps, resolve);
});
}
function showErrorMessage() {
return getRequirePromise(['alert']).then(function (alert) {
return alert(globalize.translate('MessagePlayAccessRestricted')).then(function () {
return Promise.reject();
});
@ -19,7 +16,6 @@ define(['connectionManager', 'globalize'], function (connectionManager, globaliz
}
function PlayAccessValidation() {
this.name = 'Playback validation';
this.type = 'preplayintercept';
this.id = 'playaccessvalidation';
@ -27,7 +23,6 @@ define(['connectionManager', 'globalize'], function (connectionManager, globaliz
}
PlayAccessValidation.prototype.intercept = function (options) {
var item = options.item;
if (!item) {
return Promise.resolve();
@ -38,7 +33,6 @@ define(['connectionManager', 'globalize'], function (connectionManager, globaliz
}
return connectionManager.getApiClient(serverId).getCurrentUser().then(function (user) {
if (user.Policy.EnableMediaPlayback) {
return Promise.resolve();
}

View File

@ -1,80 +0,0 @@
define(['playbackManager', 'itemHelper'], function (playbackManager, itemHelper) {
"use strict";
function getRequirePromise(deps) {
return new Promise(function (resolve, reject) {
require(deps, resolve);
});
}
function validatePlayback(options) {
var feature = 'playback';
if (options.item && (options.item.Type === 'TvChannel' || options.item.Type === 'Recording')) {
feature = 'livetv';
}
if (feature === 'playback') {
var player = playbackManager.getCurrentPlayer();
if (player && !player.isLocalPlayer) {
return Promise.resolve();
}
}
return getRequirePromise(["registrationServices"]).then(function (registrationServices) {
return registrationServices.validateFeature(feature, options).then(function (result) {
if (result && result.enableTimeLimit) {
startAutoStopTimer();
}
});
});
}
var autoStopTimeout;
function startAutoStopTimer() {
stopAutoStopTimer();
autoStopTimeout = setTimeout(onAutoStopTimeout, 63000);
}
function onAutoStopTimeout() {
stopAutoStopTimer();
playbackManager.stop();
}
function stopAutoStopTimer() {
var timeout = autoStopTimeout;
if (timeout) {
clearTimeout(timeout);
autoStopTimeout = null;
}
}
function PlaybackValidation() {
this.name = 'Playback validation';
this.type = 'preplayintercept';
this.id = 'playbackvalidation';
this.order = -1;
}
PlaybackValidation.prototype.intercept = function (options) {
// Don't care about video backdrops, or theme music or any kind of non-fullscreen playback
if (!options.fullscreen) {
return Promise.resolve();
}
if (options.item && itemHelper.isLocalItem(options.item)) {
return Promise.resolve();
}
return validatePlayback(options);
};
return PlaybackValidation;
});

View File

@ -1,4 +1,4 @@
define(['globalize', 'connectionManager', 'require', 'loading', 'apphost', 'dom', 'recordingHelper', 'events', 'registrationServices', 'paper-icon-button-light', 'emby-button', 'css!./recordingfields'], function (globalize, connectionManager, require, loading, appHost, dom, recordingHelper, events, registrationServices) {
define(['globalize', 'connectionManager', 'require', 'loading', 'apphost', 'dom', 'recordingHelper', 'events', 'paper-icon-button-light', 'emby-button', 'css!./recordingfields'], function (globalize, connectionManager, require, loading, appHost, dom, recordingHelper, events) {
'use strict';
function onRecordingButtonClick(e) {

View File

@ -1,81 +1,11 @@
define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loading', 'apphost', 'dom', 'recordingHelper', 'events', 'registrationServices', 'paper-icon-button-light', 'emby-button', 'css!./recordingfields', 'flexStyles'], function (globalize, connectionManager, serverNotifications, require, loading, appHost, dom, recordingHelper, events, registrationServices) {
define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loading', 'apphost', 'dom', 'recordingHelper', 'events', 'paper-icon-button-light', 'emby-button', 'css!./recordingfields', 'flexStyles'], function (globalize, connectionManager, serverNotifications, require, loading, appHost, dom, recordingHelper, events) {
'use strict';
function getRegistration(apiClient, feature) {
return registrationServices.validateFeature(feature, {
showDialog: false,
viewOnly: true
});
}
function showConvertRecordingsUnlockMessage(context, apiClient) {
getRegistration(apiClient, getDvrFeatureCode()).then(function () {
context.querySelector('.convertRecordingsContainer').classList.add('hide');
}, function () {
context.querySelector('.convertRecordingsContainer').classList.remove('hide');
});
}
function showSeriesRecordingFields(context, programId, apiClient) {
getRegistration(apiClient, getDvrFeatureCode()).then(function () {
context.querySelector('.supporterContainer').classList.add('hide');
context.querySelector('.convertRecordingsContainer').classList.add('hide');
context.querySelector('.recordSeriesContainer').classList.remove('hide');
}, function () {
context.querySelector('.supporterContainerText').innerHTML = globalize.translate('MessageActiveSubscriptionRequiredSeriesRecordings');
context.querySelector('.supporterContainer').classList.remove('hide');
context.querySelector('.recordSeriesContainer').classList.add('hide');
context.querySelector('.convertRecordingsContainer').classList.add('hide');
});
}
function getDvrFeatureCode() {
return 'dvr';
}
function showSingleRecordingFields(context, programId, apiClient) {
getRegistration(apiClient, getDvrFeatureCode()).then(function () {
context.querySelector('.supporterContainer').classList.add('hide');
showConvertRecordingsUnlockMessage(context, apiClient);
}, function () {
context.querySelector('.supporterContainerText').innerHTML = globalize.translate('DvrSubscriptionRequired');
context.querySelector('.supporterContainer').classList.remove('hide');
context.querySelector('.convertRecordingsContainer').classList.add('hide');
});
}
function showRecordingFieldsContainer(context, programId, apiClient) {
getRegistration(apiClient, getDvrFeatureCode()).then(function () {
context.querySelector('.recordingFields').classList.remove('hide');
}, function () {
context.querySelector('.recordingFields').classList.add('hide');
});
}
function loadData(parent, program, apiClient) {
if (program.IsSeries) {
parent.querySelector('.recordSeriesContainer').classList.remove('hide');
showSeriesRecordingFields(parent, program.Id, apiClient);
} else {
parent.querySelector('.recordSeriesContainer').classList.add('hide');
showSingleRecordingFields(parent, program.Id, apiClient);
}
if (program.SeriesTimerId) {
@ -91,13 +21,11 @@ define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loa
if (program.TimerId && program.Status !== 'Cancelled') {
parent.querySelector('.btnManageRecording').classList.remove('hide');
parent.querySelector('.singleRecordingButton .recordingIcon').classList.add('recordingIcon-active');
if (program.Status === 'InProgress') {
parent.querySelector('.singleRecordingButton .buttonText').innerHTML = globalize.translate('StopRecording');
} else {
parent.querySelector('.singleRecordingButton .buttonText').innerHTML = globalize.translate('DoNotRecord');
}
} else {
parent.querySelector('.btnManageRecording').classList.add('hide');
parent.querySelector('.singleRecordingButton .recordingIcon').classList.remove('recordingIcon-active');
@ -110,20 +38,16 @@ define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loa
var options = instance.options;
var apiClient = connectionManager.getApiClient(options.serverId);
showRecordingFieldsContainer(options.parent, options.programId, apiClient);
instance.querySelector('.recordingFields').classList.remove('hide');
return apiClient.getLiveTvProgram(options.programId, apiClient.getCurrentUserId()).then(function (program) {
instance.TimerId = program.TimerId;
instance.Status = program.Status;
instance.SeriesTimerId = program.SeriesTimerId;
loadData(options.parent, program, apiClient);
});
}
function onTimerChangedExternally(e, apiClient, data) {
var options = this.options;
var refresh = false;
@ -144,7 +68,6 @@ define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loa
}
function onSeriesTimerChangedExternally(e, apiClient, data) {
var options = this.options;
var refresh = false;
@ -181,26 +104,16 @@ define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loa
events.on(serverNotifications, 'SeriesTimerCancelled', seriesTimerChangedHandler);
}
function onSupporterButtonClick() {
registrationServices.showPremiereInfo();
}
function onManageRecordingClick(e) {
var options = this.options;
if (!this.TimerId || this.Status === 'Cancelled') {
return;
}
var self = this;
require(['recordingEditor'], function (recordingEditor) {
recordingEditor.show(self.TimerId, options.serverId, {
enableCancel: false
}).then(function () {
self.changed = true;
});
@ -281,22 +194,16 @@ define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loa
var isChecked = !button.querySelector('i').classList.contains('recordingIcon-active');
if (isChecked) {
showSeriesRecordingFields(options.parent, options.programId, apiClient);
context.querySelector('.recordSeriesContainer').classList.remove('hide');
if (!this.SeriesTimerId) {
var promise = this.TimerId ?
recordingHelper.changeRecordingToSeries(apiClient, this.TimerId, options.programId) :
recordingHelper.createRecording(apiClient, options.programId, true);
promise.then(function () {
fetchData(self);
});
}
} else {
showSingleRecordingFields(options.parent, options.programId, apiClient);
if (this.SeriesTimerId) {
apiClient.cancelLiveTvSeriesTimer(this.SeriesTimerId).then(function () {
sendToast(globalize.translate('RecordingCancelled'));
@ -307,22 +214,13 @@ define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loa
}
RecordingEditor.prototype.embed = function () {
var self = this;
return new Promise(function (resolve, reject) {
require(['text!./recordingfields.template.html'], function (template) {
var options = self.options;
var context = options.parent;
context.innerHTML = globalize.translateDocument(template, 'core');
var supporterButtons = context.querySelectorAll('.btnSupporter');
for (var i = 0, length = supporterButtons.length; i < length; i++) {
supporterButtons[i].addEventListener('click', onSupporterButtonClick);
}
context.querySelector('.singleRecordingButton').addEventListener('click', onRecordChange.bind(self));
context.querySelector('.seriesRecordingButton').addEventListener('click', onRecordSeriesChange.bind(self));
context.querySelector('.btnManageRecording').addEventListener('click', onManageRecordingClick.bind(self));
@ -334,17 +232,14 @@ define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loa
};
RecordingEditor.prototype.hasChanged = function () {
return this.changed;
};
RecordingEditor.prototype.refresh = function () {
fetchData(this);
};
RecordingEditor.prototype.destroy = function () {
var timerChangedHandler = this.timerChangedHandler;
this.timerChangedHandler = null;

View File

@ -1,20 +1,4 @@
<div class="convertRecordingsContainer hide infoBanner" style="margin: 1em 0 2em;">
<h1 style="margin: .25em 0 .5em;">${HeaderConvertYourRecordings}</h1>
<div class="fieldDescription">${PromoConvertRecordingsToStreamingFormat}</div>
<br />
<button is="emby-button" type="button" class="raised btnSupporter btnSupporterForConverting button-submit">
<span>${HeaderLearnMore}</span>
</button>
</div>
<div class="supporterContainer hide infoBanner" style="margin: 1em 0 2em;">
<div class="supporterContainerText"></div>
<br />
<button is="emby-button" type="button" class="btnSupporter raised button-submit block">
<span>${HeaderBecomeProjectSupporter}</span>
</button>
</div>
<div class="recordingFields hide">
<div class="recordSeriesContainer recordingFields-buttons flex align-items-center hide">
<div>
<button is="emby-button" type="button" class="raised recordingButton seriesRecordingButton">

View File

@ -1,4 +1,4 @@
define(['globalize', 'loading', 'connectionManager', 'registrationServices'], function (globalize, loading, connectionManager, registrationServices) {
define(['globalize', 'loading', 'connectionManager'], function (globalize, loading, connectionManager) {
'use strict';
function changeRecordingToSeries(apiClient, timerId, programId, confirmTimerCancellation) {
@ -190,30 +190,21 @@ define(['globalize', 'loading', 'connectionManager', 'registrationServices'], fu
}
function toggleRecording(serverId, programId, timerId, timerStatus, seriesTimerId) {
return registrationServices.validateFeature('dvr').then(function () {
var apiClient = connectionManager.getApiClient(serverId);
var hasTimer = timerId && timerStatus !== 'Cancelled';
if (seriesTimerId && hasTimer) {
// cancel
return showMultiCancellationPrompt(serverId, programId, timerId, timerStatus, seriesTimerId);
} else if (hasTimer && programId) {
// change to series recording, if possible
// otherwise cancel individual recording
return changeRecordingToSeries(apiClient, timerId, programId, true);
} else if (programId) {
// schedule recording
return createRecording(apiClient, programId);
} else {
return Promise.reject();
}
});
}
return {

View File

@ -1,16 +0,0 @@
define(['appSettings', 'loading', 'apphost', 'events', 'shell', 'globalize', 'dialogHelper', 'connectionManager', 'layoutManager', 'emby-button', 'emby-linkbutton'], function (appSettings, loading, appHost, events, shell, globalize, dialogHelper, connectionManager, layoutManager) {
'use strict';
function validateFeature(feature, options) {
return Promise.resolve();
}
function showPremiereInfo() {
return Promise.resolve();
}
return {
validateFeature: validateFeature,
showPremiereInfo: showPremiereInfo
};
});

View File

@ -4,20 +4,14 @@
var connectionManager;
function getApiClient(serverId) {
if (connectionManager) {
return Promise.resolve(connectionManager.getApiClient(serverId));
}
//importScripts('serviceworker-cache-polyfill.js');
return Promise.reject();
}
function executeAction(action, data, serverId) {
return getApiClient(serverId).then(function (apiClient) {
switch (action) {
case 'cancel-install':
var id = data.id;
@ -32,7 +26,6 @@
}
self.addEventListener('notificationclick', function (event) {
var notification = event.notification;
notification.close();
@ -47,6 +40,5 @@
}
event.waitUntil(executeAction(action, data, serverId));
}, false);
})();

View File

@ -1,6 +0,0 @@
self.addEventListener('sync', function (event) {
'use strict';
if (event.tag === 'emby-sync') {
}
});

View File

@ -9,13 +9,11 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr
function getRequirePromise(deps) {
return new Promise(function (resolve, reject) {
require(deps, resolve);
});
}
function loadSkin(id) {
var newSkin = pluginManager.plugins().filter(function (p) {
return p.id === id;
})[0];
@ -29,7 +27,6 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr
var unloadPromise;
if (currentSkin) {
if (currentSkin.id === newSkin.id) {
// Nothing to do, it's already the active skin
return Promise.resolve(currentSkin);
@ -72,7 +69,6 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr
console.log('Unloading skin: ' + skin.name);
// TODO: unload css
return skin.unload().then(function () {
document.dispatchEvent(new CustomEvent("skinunload", {
detail: {
@ -83,9 +79,7 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr
}
function loadSkinHeader(skin) {
return getSkinHeader(skin).then(function (headerHtml) {
document.querySelector('.skinHeader').innerHTML = headerHtml;
currentSkin = skin;
@ -175,29 +169,7 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr
getThemes: getThemes
};
function onRegistrationSuccess() {
appSettings.set('appthemesregistered', 'true');
}
function onRegistrationFailure() {
appSettings.set('appthemesregistered', 'false');
}
function isRegistered() {
getRequirePromise(['registrationServices']).then(function (registrationServices) {
registrationServices.validateFeature('themes', {
showDialog: false
}).then(onRegistrationSuccess, onRegistrationFailure);
});
return appSettings.get('appthemesregistered') !== 'false';
}
function getThemeStylesheetInfo(id, requiresRegistration, isDefaultProperty) {
var themes = skinManager.getThemes();
var defaultTheme;
var selectedTheme;
@ -214,11 +186,6 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr
}
selectedTheme = selectedTheme || defaultTheme;
if (selectedTheme.id !== defaultTheme.id && requiresRegistration && !isRegistered()) {
selectedTheme = defaultTheme;
}
return {
stylesheetPath: require.toUrl('components/themes/' + selectedTheme.id + '/theme.css'),
themeId: selectedTheme.id
@ -230,9 +197,7 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr
var currentSound;
function loadThemeResources(id) {
lastSound = 0;
if (currentSound) {
currentSound.stop();
currentSound = null;
@ -243,26 +208,19 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr
function onThemeLoaded() {
document.documentElement.classList.remove('preload');
try {
var color = getComputedStyle(document.querySelector('.skinHeader')).getPropertyValue("background-color");
if (color) {
appHost.setThemeColor(color);
}
}
catch (err) {
} catch (err) {
console.log('Error setting theme color: ' + err);
}
}
skinManager.setTheme = function (id, context) {
return new Promise(function (resolve, reject) {
var requiresRegistration = true;
if (currentThemeId && currentThemeId === id) {
resolve();
return;
@ -270,22 +228,18 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr
var isDefaultProperty = context === 'serverdashboard' ? 'isDefaultServerDashboard' : 'isDefault';
var info = getThemeStylesheetInfo(id, requiresRegistration, isDefaultProperty);
if (currentThemeId && currentThemeId === info.themeId) {
resolve();
return;
}
var linkUrl = info.stylesheetPath;
unloadTheme();
var link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('type', 'text/css');
link.onload = function () {
onThemeLoaded();
resolve();
};
@ -301,23 +255,19 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr
};
function onViewBeforeShow(e) {
if (e.detail && e.detail.type === 'video-osd') {
return;
}
if (themeResources.backdrop) {
backdrop.setBackdrop(themeResources.backdrop);
}
if (!browser.mobile && userSettings.enableThemeSongs()) {
if (lastSound === 0) {
if (themeResources.themeSong) {
playSound(themeResources.themeSong);
}
} else if ((new Date().getTime() - lastSound) > 30000) {
if (themeResources.effect) {
playSound(themeResources.effect);

View File

@ -1,188 +0,0 @@
define(['connectionManager', 'serverNotifications', 'events', 'globalize', 'emby-button'], function (connectionManager, serverNotifications, events, globalize, EmbyButtonPrototype) {
'use strict';
function onClick(e) {
var button = this;
var id = button.getAttribute('data-id');
var serverId = button.getAttribute('data-serverid');
var apiClient = connectionManager.getApiClient(serverId);
if (!button.classList.contains('downloadbutton-on')) {
require(['syncDialog'], function (syncDialog) {
syncDialog.showMenu({
items: [id],
mode: 'download',
serverId: serverId
}).then(function () {
button.dispatchEvent(new CustomEvent('download', {
cancelable: false
}));
});
});
} else {
require(['confirm'], function (confirm) {
confirm({
text: globalize.translate('ConfirmRemoveDownload'),
confirmText: globalize.translate('RemoveDownload'),
cancelText: globalize.translate('KeepDownload'),
primary: 'cancel'
}).then(function () {
apiClient.cancelSyncItems([id]);
button.dispatchEvent(new CustomEvent('download-cancel', {
cancelable: false
}));
});
});
}
}
function updateSyncStatus(button, syncPercent) {
var icon = button.iconElement;
if (!icon) {
button.iconElement = button.querySelector('i');
icon = button.iconElement;
}
if (syncPercent != null) {
button.classList.add('downloadbutton-on');
if (icon) {
icon.classList.add('downloadbutton-icon-on');
}
} else {
button.classList.remove('downloadbutton-on');
if (icon) {
icon.classList.remove('downloadbutton-icon-on');
}
}
if ((syncPercent || 0) >= 100) {
button.classList.add('downloadbutton-complete');
if (icon) {
icon.classList.add('downloadbutton-icon-complete');
}
} else {
button.classList.remove('downloadbutton-complete');
if (icon) {
icon.classList.remove('downloadbutton-icon-complete');
}
}
var text;
if ((syncPercent || 0) >= 100) {
text = globalize.translate('Downloaded');
} else if (syncPercent != null) {
text = globalize.translate('Downloading');
} else {
text = globalize.translate('Download');
}
var textElement = button.querySelector('.emby-downloadbutton-downloadtext');
if (textElement) {
textElement.innerHTML = text;
}
button.title = text;
}
function clearEvents(button) {
button.removeEventListener('click', onClick);
}
function bindEvents(button) {
clearEvents(button);
button.addEventListener('click', onClick);
}
var EmbyDownloadButtonPrototype = Object.create(EmbyButtonPrototype);
EmbyDownloadButtonPrototype.createdCallback = function () {
// base method
if (EmbyButtonPrototype.createdCallback) {
EmbyButtonPrototype.createdCallback.call(this);
}
};
EmbyDownloadButtonPrototype.attachedCallback = function () {
// base method
if (EmbyButtonPrototype.attachedCallback) {
EmbyButtonPrototype.attachedCallback.call(this);
}
var itemId = this.getAttribute('data-id');
var serverId = this.getAttribute('data-serverid');
if (itemId && serverId) {
bindEvents(this);
}
};
EmbyDownloadButtonPrototype.detachedCallback = function () {
// base method
if (EmbyButtonPrototype.detachedCallback) {
EmbyButtonPrototype.detachedCallback.call(this);
}
clearEvents(this);
this.iconElement = null;
};
function fetchAndUpdate(button, item) {
connectionManager.getApiClient(item.ServerId).getSyncStatus(item.Id).then(function (result) {
updateSyncStatus(button, result.Progress);
}, function () {
});
}
EmbyDownloadButtonPrototype.setItem = function (item) {
if (item) {
this.setAttribute('data-id', item.Id);
this.setAttribute('data-serverid', item.ServerId);
fetchAndUpdate(this, item);
bindEvents(this);
} else {
this.removeAttribute('data-id');
this.removeAttribute('data-serverid');
clearEvents(this);
}
};
document.registerElement('emby-downloadbutton', {
prototype: EmbyDownloadButtonPrototype,
extends: 'button'
});
});

View File

@ -1,736 +0,0 @@
define(['apphost', 'globalize', 'connectionManager', 'layoutManager', 'focusManager', 'scrollHelper', 'appSettings', 'registrationServices', 'dialogHelper', 'paper-icon-button-light', 'formDialogStyle'], function (appHost, globalize, connectionManager, layoutManager, focusManager, scrollHelper, appSettings, registrationServices, dialogHelper) {
'use strict';
var currentDialogOptions;
function submitJob(dlg, apiClient, userId, syncOptions, form) {
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('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) {
showSubmissionToast(target, apiClient);
if (syncOptions.mode === 'download') {
syncNow();
}
});
});
return true;
}
function showSubmissionToast(targetId, apiClient) {
require(['toast'], function (toast) {
var msg = targetId === apiClient.deviceId() ?
globalize.translate('DownloadingDots') :
globalize.translate('SyncingDots');
toast(msg);
});
}
function syncNow() {
require(['localsync'], function (localSync) {
localSync.sync();
});
}
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) {
showSubmissionToast(targetId, apiClient);
if (syncOptions.mode === 'download') {
syncNow();
}
});
});
}
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 selectQuality = form.querySelector('#selectQuality');
if (selectQuality) {
job.Quality = selectQuality.value;
appSettings.set('sync-lastquality', job.Quality || '');
}
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 () {
renderFormInternal(options, connectionManager.deviceId(), resolve);
});
});
}
function renderFormInternal(options, defaultTargetId, resolve) {
var elem = options.elem;
var dialogOptions = options.dialogOptions;
var targets = dialogOptions.Targets;
var html = '';
var mode = options.mode;
var targetContainerClass = mode === 'download' ? ' hide' : '';
var syncTargetLabel = mode === 'convert' ? globalize.translate('LabelConvertTo') : globalize.translate('LabelSyncTo');
if (options.readOnlySyncTarget) {
html += '<div class="inputContainer' + targetContainerClass + '">';
html += '<input is="emby-input" type="text" id="selectSyncTarget" readonly label="' + syncTargetLabel + '"/>';
html += '</div>';
} else {
html += '<div class="selectContainer' + targetContainerClass + '">';
html += '<select is="emby-select" id="selectSyncTarget" required="required" label="' + syncTargetLabel + '">';
html += targets.map(function (t) {
var isSelected = defaultTargetId === t.Id;
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>';
}
if (appHost.supports('externallinks')) {
html += '<div class="fieldDescription"><a is="emby-linkbutton" class="button-link lnkLearnMore" href="https://github.com/MediaBrowser/Wiki/wiki/Sync" target="_blank">' + globalize.translate('LearnMore') + '</a></div>';
}
html += '</div>';
}
html += '<div class="fldProfile selectContainer hide">';
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 hide">';
html += '<select is="emby-select" id="selectQuality" required="required" label="' + globalize.translate('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('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"/>';
if (mode === 'convert') {
html += '<span>' + globalize.translate('ConvertUnwatchedVideosOnly') + '</span>';
} else {
html += '<span>' + globalize.translate('SyncUnwatchedVideosOnly') + '</span>';
}
html += '</label>';
if (mode === 'convert') {
html += '<div class="fieldDescription checkboxFieldDescription">' + globalize.translate('ConvertUnwatchedVideosOnlyHelp') + '</div>';
} else {
html += '<div class="fieldDescription checkboxFieldDescription">' + globalize.translate('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"/>';
if (mode === 'convert') {
html += '<span>' + globalize.translate('AutomaticallyConvertNewContent') + '</span>';
} else {
html += '<span>' + globalize.translate('AutomaticallySyncNewContent') + '</span>';
}
html += '</label>';
if (mode === 'convert') {
html += '<div class="fieldDescription checkboxFieldDescription">' + globalize.translate('AutomaticallyConvertNewContentHelp') + '</div>';
} else {
html += '<div class="fieldDescription checkboxFieldDescription">' + globalize.translate('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('LabelItemLimit') + '"/>';
if (mode === 'convert') {
html += '<div class="fieldDescription">' + globalize.translate('ConvertItemLimitHelp') + '</div>';
} else {
html += '<div class="fieldDescription">' + globalize.translate('DownloadItemLimitHelp') + '</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);
});
if (dialogOptions.ProfileOptions.length) {
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
}));
}
// This isn't ideal, but allow time for the change handlers above to run
setTimeout(function () {
focusManager.autoFocus(elem);
}, 100);
}
function showWifiMessage() {
require(['dialog', 'appRouter'], function (dialog, appRouter) {
var options = {
title: globalize.translate('HeaderWaitingForWifi'),
text: globalize.translate('WifiRequiredToDownload')
};
var items = [];
items.push({
name: options.confirmText || globalize.translate('ButtonOk'),
id: 'ok',
type: 'submit'
});
items.push({
name: options.cancelText || globalize.translate('HeaderDownloadSettings'),
id: 'downloadsettings',
type: 'cancel'
});
options.buttons = items;
dialog(options).then(function (result) {
if (result === 'ok') {
return Promise.resolve();
}
if (result === 'downloadsettings') {
appRouter.show(appRouter.getRouteUrl('downloadsettings'));
return Promise.resolve();
}
return Promise.reject();
});
});
}
function validateNetwork() {
var network = navigator.connection ? navigator.connection.type : null;
switch (network) {
case 'cellular':
case 'bluetooth':
showWifiMessage();
return false;
default:
return true;
}
}
function showSyncMenu(options) {
if (options.mode === 'download' && appSettings.syncOnlyOnWifi() && !validateNetwork()) {
return Promise.reject();
}
return registrationServices.validateFeature('sync').then(function () {
return showSyncMenuInternal(options);
});
}
function enableAutoSync(options) {
if (options.mode !== 'download') {
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;
}
if (firstItem.Type === 'Playlist' && firstItem.MediaType === 'Audio') {
return true;
}
return false;
}
function showSyncMenuInternal(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 dialogOptionsFn = getTargetDialogOptionsFn(apiClient, {
UserId: userId,
ItemIds: (options.items || []).map(function (i) {
return i.Id || i;
}).join(','),
ParentId: options.ParentId,
Category: options.Category,
IncludeProviders: options.mode === 'convert' ? 'ConvertSyncProvider' : null,
ExcludeProviders: options.mode === 'convert' ? null : 'ConvertSyncProvider'
});
return dialogOptionsFn().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">&#xE5C4;</i></button>';
html += '<h3 class="formDialogHeaderTitle">';
var syncButtonLabel = options.mode === 'download' ?
globalize.translate('Download') :
(options.mode === 'convert' ? globalize.translate('Convert') : globalize.translate('Sync'));
html += syncButtonLabel;
html += '</h3>';
if (appHost.supports('externallinks')) {
html += '<a is="emby-linkbutton" href="https://github.com/MediaBrowser/Wiki/wiki/Sync" target="_blank" class="button-link lnkHelp" style="margin-top:0;display:inline-block;vertical-align:middle;margin-left:auto;"><i class="md-icon">info</i><span>' + globalize.translate('Help') + '</span></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 += '<div class="formDialogFooter">';
html += '<button is="emby-button" type="submit" class="raised button-submit block formDialogFooterItem"><span>' + syncButtonLabel + '</span></button>';
html += '</div>';
html += '</form>';
html += '</div>';
html += '</div>';
dlg.innerHTML = html;
var submitted = false;
dlg.querySelector('form').addEventListener('submit', function (e) {
submitted = submitJob(dlg, apiClient, userId, options, this);
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: dialogOptionsFn,
mode: options.mode
});
return promise.then(function () {
if (layoutManager.tv) {
scrollHelper.centerFocus.off(dlg.querySelector('.formDialogContent'), false);
}
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');
// This is a hack due to what appears to be a edge bug but it shoudln't matter as the list always has selectable items
selectQuality.removeAttribute('required');
}
} else {
if (fldQuality) {
fldQuality.classList.add('hide');
}
if (selectQuality) {
selectQuality.removeAttribute('required');
}
}
}
function onProfileChange(form, profileId) {
var options = currentDialogOptions || {};
var profileOptions = options.ProfileOptions || [];
if (!profileOptions.length) {
return;
}
var option = 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('');
var lastQuality = appSettings.get('sync-lastquality');
if (lastQuality && options.QualityOptions.filter(function (i) {
return i.Id === lastQuality;
}).length) {
selectQuality.value = lastQuality;
}
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
};
});

View File

@ -104,18 +104,6 @@
<span>${ButtonShuffle}</span>
</button>
<button is="emby-downloadbutton" type="button" class="button-flat btnSyncDownload hide detailButton-mobile">
<div class="detailButton-mobile-content">
<i class="md-icon detailButton-mobile-icon">&#xE2C4;</i>
<div class="detailButton-mobile-text emby-downloadbutton-downloadtext">${ButtonDownload}</div>
</div>
</button>
<button is="emby-downloadbutton" type="button" class="raised btnSyncDownload hide detailButton">
<i class="md-icon">&#xE2C4;</i>
<span class="emby-downloadbutton-downloadtext">${ButtonDownload}</span>
</button>
<button is="emby-button" type="button" class="button-flat btnCancelSeriesTimer hide detailButton-mobile">
<div class="detailButton-mobile-content">
<i class="md-icon detailButton-mobile-icon">&#xE872;</i>

View File

@ -74,10 +74,6 @@
<h2 class="sectionTitle sectionTitle-cards">${HeaderLatestRecordings}</h2>
<i class="md-icon">&#xE5CC;</i>
</button>
<button is="emby-button" type="button" class="fab submit categorySyncButton button-submit sectionTitleButton" data-category="Latest" title="${ButtonDownload}">
<i class="md-icon">&#xE2C4;</i>
</button>
</div>
<div is="emby-itemscontainer" class="recordingItems itemsContainer padded-left padded-right"></div>
</div>

View File

@ -30,9 +30,6 @@
<div class="verticalSection">
<div class="sectionTitleContainer sectionTitleContainer-cards">
<h2 class="sectionTitle sectionTitle-cards padded-left">${HeaderLatestMovies}</h2>
<button is="emby-button" type="button" class="fab submit categorySyncButton button-submit sectionTitleButton" data-category="Latest" title="${ButtonDownload}">
<i class="md-icon">&#xE2C4;</i>
</button>
</div>
<div is="emby-itemscontainer" id="recentlyAddedItems" class="itemsContainer padded-left padded-right">

View File

@ -1,4 +1,4 @@
define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuilder", "datetime", "mediaInfo", "backdrop", "listView", "itemContextMenu", "itemHelper", "dom", "indicators", "apphost", "imageLoader", "libraryMenu", "globalize", "browser", "events", "scrollHelper", "playbackManager", "libraryBrowser", "scrollStyles", "emby-itemscontainer", "emby-checkbox", "emby-linkbutton", "emby-playstatebutton", "emby-ratingbutton", "emby-downloadbutton", "emby-scroller", "emby-select"], function(loading, appRouter, layoutManager, connectionManager, cardBuilder, datetime, mediaInfo, backdrop, listView, itemContextMenu, itemHelper, dom, indicators, appHost, imageLoader, libraryMenu, globalize, browser, events, scrollHelper, playbackManager, libraryBrowser) {
define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuilder", "datetime", "mediaInfo", "backdrop", "listView", "itemContextMenu", "itemHelper", "dom", "indicators", "apphost", "imageLoader", "libraryMenu", "globalize", "browser", "events", "scrollHelper", "playbackManager", "libraryBrowser", "scrollStyles", "emby-itemscontainer", "emby-checkbox", "emby-linkbutton", "emby-playstatebutton", "emby-ratingbutton", "emby-scroller", "emby-select"], function(loading, appRouter, layoutManager, connectionManager, cardBuilder, datetime, mediaInfo, backdrop, listView, itemContextMenu, itemHelper, dom, indicators, appHost, imageLoader, libraryMenu, globalize, browser, events, scrollHelper, playbackManager, libraryBrowser) {
"use strict";
function getPromise(apiClient, params) {
@ -33,12 +33,7 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild
user: user,
share: !0
};
return appHost.supports("sync") && (options.syncLocal = !1), options
}
function renderSyncLocalContainer(page, params, user, item) {
if (appHost.supports("sync"))
for (var canSync = itemHelper.canSync(user, item), buttons = page.querySelectorAll(".btnSyncDownload"), i = 0, length = buttons.length; i < length; i++) buttons[i].setItem(item), canSync ? buttons[i].classList.remove("hide") : buttons[i].classList.add("hide")
return options;
}
function getProgramScheduleHtml(items, options) {
@ -286,7 +281,23 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild
var apiClient = connectionManager.getApiClient(item.ServerId);
renderSeriesTimerEditor(page, item, apiClient, user), renderTimerEditor(page, item, apiClient, user), renderImage(page, item, apiClient, user), renderLogo(page, item, apiClient), setTitle(item, apiClient), setInitialCollapsibleState(page, item, apiClient, context, user), renderDetails(page, item, apiClient, context), renderTrackSelections(page, instance, item), dom.getWindowSize().innerWidth >= 1e3 ? backdrop.setBackdrops([item]) : backdrop.clear(), renderDetailPageBackdrop(page, item, apiClient);
var canPlay = reloadPlayButtons(page, item);
(item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && -1 !== playbackManager.getSupportedCommands().indexOf("PlayTrailers") ? hideAll(page, "btnPlayTrailer", !0) : hideAll(page, "btnPlayTrailer"), setTrailerButtonVisibility(page, item), item.CanDelete && !item.IsFolder ? hideAll(page, "btnDeleteItem", !0) : hideAll(page, "btnDeleteItem"), renderSyncLocalContainer(page, params, user, item), "Program" !== item.Type || canPlay ? hideAll(page, "mainDetailButtons", !0) : hideAll(page, "mainDetailButtons"), showRecordingFields(instance, page, item, user);
if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && -1 !== playbackManager.getSupportedCommands().indexOf("PlayTrailers")) {
hideAll(page, "btnPlayTrailer", true);
} else {
hideAll(page, "btnPlayTrailer");
}
setTrailerButtonVisibility(page, item);
if (item.CanDelete && !item.IsFolder) {
hideAll(page, "btnDeleteItem", true);
} else {
hideAll(page, "btnDeleteItem");
}
if ("Program" !== item.Type || canPlay) {
hideAll(page, "mainDetailButtons", true);
} else {
hideAll(page, "mainDetailButtons");
}
showRecordingFields(instance, page, item, user);
var groupedVersions = (item.MediaSources || []).filter(function(g) {
return "Grouping" == g.Type
});
@ -1166,30 +1177,55 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild
}))
}
}
var currentItem, self = this,
apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient;
var currentItem;
var self = this;
var apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient;
view.querySelectorAll(".btnPlay");
bindAll(view, ".btnPlay", "click", onPlayClick), bindAll(view, ".btnResume", "click", onPlayClick), bindAll(view, ".btnInstantMix", "click", onInstantMixClick), bindAll(view, ".btnShuffle", "click", onShuffleClick), bindAll(view, ".btnPlayTrailer", "click", onPlayTrailerClick), bindAll(view, ".btnCancelSeriesTimer", "click", onCancelSeriesTimerClick), bindAll(view, ".btnCancelTimer", "click", onCancelTimerClick), bindAll(view, ".btnDeleteItem", "click", onDeleteClick), bindAll(view, ".btnSyncDownload", "download", onDownloadChange), bindAll(view, ".btnSyncDownload", "download-cancel", onDownloadChange), view.querySelector(".btnMoreCommands i").innerHTML = "&#xE5D3;", view.querySelector(".trackSelections").addEventListener("submit", onTrackSelectionsSubmit), view.querySelector(".btnSplitVersions").addEventListener("click", function() {
bindAll(view, ".btnPlay", "click", onPlayClick);
bindAll(view, ".btnResume", "click", onPlayClick);
bindAll(view, ".btnInstantMix", "click", onInstantMixClick);
bindAll(view, ".btnShuffle", "click", onShuffleClick);
bindAll(view, ".btnPlayTrailer", "click", onPlayTrailerClick);
bindAll(view, ".btnCancelSeriesTimer", "click", onCancelSeriesTimerClick);
bindAll(view, ".btnCancelTimer", "click", onCancelTimerClick);
bindAll(view, ".btnDeleteItem", "click", onDeleteClick);
view.querySelector(".btnMoreCommands i").innerHTML = "&#xE5D3;";
view.querySelector(".trackSelections").addEventListener("submit", onTrackSelectionsSubmit);
view.querySelector(".btnSplitVersions").addEventListener("click", function() {
splitVersions(self, view, apiClient, params)
}), bindAll(view, ".btnMoreCommands", "click", onMoreCommandsClick), view.querySelector(".selectSource").addEventListener("change", function() {
renderVideoSelections(view, self._currentPlaybackMediaSources), renderAudioSelections(view, self._currentPlaybackMediaSources), renderSubtitleSelections(view, self._currentPlaybackMediaSources)
}), view.addEventListener("click", function(e) {
});
bindAll(view, ".btnMoreCommands", "click", onMoreCommandsClick);
view.querySelector(".selectSource").addEventListener("change", function() {
renderVideoSelections(view, self._currentPlaybackMediaSources);
renderAudioSelections(view, self._currentPlaybackMediaSources);
renderSubtitleSelections(view, self._currentPlaybackMediaSources);
});
view.addEventListener("click", function(e) {
dom.parentWithClass(e.target, "moreScenes") ? apiClient.getCurrentUser().then(function(user) {
renderScenes(view, currentItem)
}) : dom.parentWithClass(e.target, "morePeople") ? renderCast(view, currentItem, params.context) : dom.parentWithClass(e.target, "moreSpecials") && apiClient.getCurrentUser().then(function(user) {
renderSpecials(view, currentItem, user)
})
}), view.querySelector(".detailImageContainer").addEventListener("click", function(e) {
});
view.querySelector(".detailImageContainer").addEventListener("click", function(e) {
dom.parentWithClass(e.target, "itemDetailGalleryLink") && editImages().then(function() {
reload(self, view, params)
})
}), view.addEventListener("viewshow", function(e) {
});
view.addEventListener("viewshow", function(e) {
var page = this;
libraryMenu.setTransparentMenu(!0), e.detail.isRestored ? currentItem && (setTitle(currentItem, connectionManager.getApiClient(currentItem.ServerId)), renderTrackSelections(page, self, currentItem, !0)) : reload(self, page, params), events.on(apiClient, "message", onWebSocketMessage), events.on(playbackManager, "playerchange", onPlayerChange)
}), view.addEventListener("viewbeforehide", function() {
events.off(apiClient, "message", onWebSocketMessage), events.off(playbackManager, "playerchange", onPlayerChange), libraryMenu.setTransparentMenu(!1)
}), view.addEventListener("viewdestroy", function() {
currentItem = null, self._currentPlaybackMediaSources = null, self.currentRecordingFields = null
});
view.addEventListener("viewbeforehide", function() {
events.off(apiClient, "message", onWebSocketMessage);
events.off(playbackManager, "playerchange", onPlayerChange);
libraryMenu.setTransparentMenu(false);
});
view.addEventListener("viewdestroy", function() {
currentItem = null;
self._currentPlaybackMediaSources = null;
self.currentRecordingFields = null;
})
}
});

View File

@ -1,4 +1,4 @@
define(["layoutManager", "loading", "components/categorysyncbuttons", "cardBuilder", "apphost", "imageLoader", "scripts/livetvcomponents", "listViewStyle", "emby-itemscontainer"], function(layoutManager, loading, categorysyncbuttons, cardBuilder, appHost, imageLoader) {
define(["layoutManager", "loading", "cardBuilder", "apphost", "imageLoader", "scripts/livetvcomponents", "listViewStyle", "emby-itemscontainer"], function(layoutManager, loading, cardBuilder, appHost, imageLoader) {
"use strict";
function renderRecordings(elem, recordings, cardOptions, scrollX) {
@ -54,7 +54,6 @@ define(["layoutManager", "loading", "components/categorysyncbuttons", "cardBuild
}
var foldersPromise, latestPromise, self = this,
lastFullRender = 0;
categorysyncbuttons.init(tabContent);
for (var moreButtons = tabContent.querySelectorAll(".more"), i = 0, length = moreButtons.length; i < length; i++) moreButtons[i].addEventListener("click", onMoreClick);
self.preRender = function() {
enableFullRender() && (latestPromise = ApiClient.getLiveTvRecordings({

View File

@ -1,4 +1,4 @@
define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu", "mainTabsManager", "components/categorysyncbuttons", "cardBuilder", "dom", "imageLoader", "playbackManager", "emby-itemscontainer", "emby-tabs", "emby-button"], function(events, layoutManager, inputManager, userSettings, libraryMenu, mainTabsManager, categorysyncbuttons, cardBuilder, dom, imageLoader, playbackManager) {
define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu", "mainTabsManager", "cardBuilder", "dom", "imageLoader", "playbackManager", "emby-itemscontainer", "emby-tabs", "emby-button"], function(events, layoutManager, inputManager, userSettings, libraryMenu, mainTabsManager, cardBuilder, dom, imageLoader, playbackManager) {
"use strict";
function enableScrollX() {
@ -250,7 +250,7 @@ define(["events", "layoutManager", "inputManager", "userSettings", "libraryMenu"
suggestionsTabIndex = 1;
self.initTab = function() {
var tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
categorysyncbuttons.init(tabContent), initSuggestedTab(view, tabContent)
initSuggestedTab(view, tabContent);
}, self.renderTab = function() {
var tabContent = view.querySelector(".pageTabContent[data-index='" + suggestionsTabIndex + "']");
loadSuggestionsTab(view, params, tabContent)

View File

@ -1131,7 +1131,6 @@ var AppInfo = {};
function loadPlugins(externalPlugins, appHost, browser, shell) {
console.log("Loading installed plugins");
var list = [
"components/playback/playbackvalidation",
"components/playback/playaccessvalidation",
"components/playback/experimentalwarnings",
"components/htmlaudioplayer/plugin",
@ -1431,7 +1430,6 @@ var AppInfo = {};
define("programStyles", ["css!" + componentsPath + "/guide/programs"], returnFirstDependency);
define("guide-settings-dialog", [componentsPath + "/guide/guide-settings"], returnFirstDependency);
define("loadingDialog", [componentsPath + "/loadingdialog/loadingdialog"], returnFirstDependency);
define("syncDialog", [componentsPath + "/sync/sync"], returnFirstDependency);
define("viewManager", [componentsPath + "/viewmanager/viewmanager"], function (viewManager) {
window.ViewManager = viewManager;
viewManager.dispatchPageEvents(true);
@ -1470,7 +1468,6 @@ var AppInfo = {};
define("userdataButtons", [componentsPath + "/userdatabuttons/userdatabuttons"], returnFirstDependency);
define("emby-playstatebutton", [componentsPath + "/userdatabuttons/emby-playstatebutton"], returnFirstDependency);
define("emby-ratingbutton", [componentsPath + "/userdatabuttons/emby-ratingbutton"], returnFirstDependency);
define("emby-downloadbutton", [componentsPath + "/sync/emby-downloadbutton"], returnFirstDependency);
define("listView", [componentsPath + "/listview/listview"], returnFirstDependency);
define("listViewStyle", ["css!" + componentsPath + "/listview/listview"], returnFirstDependency);
define("formDialogStyle", ["css!" + componentsPath + "/formdialog"], returnFirstDependency);
@ -1478,7 +1475,6 @@ var AppInfo = {};
define("viewSettings", [componentsPath + "/viewsettings/viewsettings"], returnFirstDependency);
define("filterMenu", [componentsPath + "/filtermenu/filtermenu"], returnFirstDependency);
define("sortMenu", [componentsPath + "/sortmenu/sortmenu"], returnFirstDependency);
define("registrationServices", [componentsPath + "/registrationservices/registrationservices"], returnFirstDependency);
if ("cordova" === self.appMode || "android" === self.appMode) {
define("fileupload", ["cordova/fileupload"], returnFirstDependency);

View File

@ -1,4 +1,4 @@
define(["loading", "components/categorysyncbuttons", "components/groupedcards", "cardBuilder", "apphost", "imageLoader"], function(loading, categorysyncbuttons, groupedcards, cardBuilder, appHost, imageLoader) {
define(["loading", "components/groupedcards", "cardBuilder", "apphost", "imageLoader"], function(loading, groupedcards, cardBuilder, appHost, imageLoader) {
"use strict";
function getLatestPromise(context, params) {
@ -43,7 +43,6 @@ define(["loading", "components/categorysyncbuttons", "components/groupedcards",
}
return function(view, params, tabContent) {
var self = this;
categorysyncbuttons.init(tabContent);
var latestPromise;
self.preRender = function() {
latestPromise = getLatestPromise(view, params)

View File

@ -1,4 +1,4 @@
define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "dom", "components/categorysyncbuttons", "userSettings", "cardBuilder", "playbackManager", "mainTabsManager", "scrollStyles", "emby-itemscontainer", "emby-button"], function(events, inputManager, libraryMenu, layoutManager, loading, dom, categorysyncbuttons, userSettings, cardBuilder, playbackManager, mainTabsManager) {
define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "dom", "userSettings", "cardBuilder", "playbackManager", "mainTabsManager", "scrollStyles", "emby-itemscontainer", "emby-button"], function(events, inputManager, libraryMenu, layoutManager, loading, dom, userSettings, cardBuilder, playbackManager, mainTabsManager) {
"use strict";
function getTabs() {
@ -204,7 +204,7 @@ define(["events", "inputManager", "libraryMenu", "layoutManager", "loading", "do
initialTabIndex = currentTabIndex;
self.initTab = function() {
var tabContent = self.tabContent;
setScrollClasses(tabContent.querySelector("#resumableItems"), enableScrollX()), categorysyncbuttons.init(tabContent)
setScrollClasses(tabContent.querySelector("#resumableItems"), enableScrollX());
}, self.renderTab = function() {
reload()
};

View File

@ -1 +1 @@
importScripts("components/serviceworker/notifications.js", "components/serviceworker/sync.js");
importScripts("components/serviceworker/notifications.js");

View File

@ -30,9 +30,6 @@
<div class="verticalSection">
<div class="sectionTitleContainer sectionTitleContainer-cards">
<h2 class="sectionTitle sectionTitle-cards padded-left nextUpHeader">${HeaderNextUp}</h2>
<button is="emby-button" type="button" class="fab submit categorySyncButton button-submit sectionTitleButton" data-category="NextUp" title="${ButtonDownload}">
<i class="md-icon">&#xE2C4;</i>
</button>
</div>
<div is="emby-itemscontainer" id="nextUpItems" class="itemsContainer vertical-wrap padded-left padded-right">
</div>
@ -43,9 +40,6 @@
<div class="verticalSection">
<div class="sectionTitleContainer sectionTitleContainer-cards">
<h2 class="sectionTitle sectionTitle-cards padded-left">${HeaderLatestEpisodes}</h2>
<button is="emby-button" type="button" class="fab submit categorySyncButton button-submit sectionTitleButton" data-category="Latest" title="${ButtonDownload}">
<i class="md-icon">&#xE2C4;</i>
</button>
</div>
<div is="emby-itemscontainer" id="latestEpisodes" class="itemsContainer vertical-wrap padded-left padded-right">
</div>