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

Merge branch 'master' into migrate-to-ES6-60

This commit is contained in:
Cameron 2020-08-06 17:50:21 +01:00 committed by GitHub
commit 37f9097ebe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
92 changed files with 1930 additions and 2579 deletions

View file

@ -1,34 +1,28 @@
define([], function() {
'use strict';
if (window.appMode === 'cordova' || window.appMode === 'android') {
return {
load: function () {
window.chrome = window.chrome || {};
class CastSenderApi {
load() {
if (window.appMode === 'cordova' || window.appMode === 'android') {
window.chrome = window.chrome || {};
return Promise.resolve();
} else {
let ccLoaded = false;
if (ccLoaded) {
return Promise.resolve();
}
};
} else {
var ccLoaded = false;
return {
load: function () {
if (ccLoaded) {
return Promise.resolve();
}
return new Promise(function (resolve, reject) {
var fileref = document.createElement('script');
fileref.setAttribute('type', 'text/javascript');
return new Promise(function (resolve) {
const fileref = document.createElement('script');
fileref.setAttribute('type', 'text/javascript');
fileref.onload = function () {
ccLoaded = true;
resolve();
};
fileref.onload = function () {
ccLoaded = true;
resolve();
};
fileref.setAttribute('src', 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js');
document.querySelector('head').appendChild(fileref);
});
}
};
fileref.setAttribute('src', 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js');
document.querySelector('head').appendChild(fileref);
});
}
}
});
}
export default CastSenderApi;

View file

@ -1,5 +1,6 @@
define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'apphost', 'inputManager', 'layoutManager', 'connectionManager', 'appRouter', 'globalize', 'userSettings', 'emby-checkbox', 'emby-input', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button', 'flexStyles'], function (require, dom, focusManager, dialogHelper, loading, appHost, inputManager, layoutManager, connectionManager, appRouter, globalize, userSettings) {
'use strict';
focusManager = focusManager.default || focusManager;
function onSubmit(e) {
e.preventDefault();

View file

@ -1,5 +1,7 @@
define(['dom', 'scrollManager'], function (dom, scrollManager) {
'use strict';
/* eslint-disable indent */
import dom from 'dom';
import scrollManager from 'scrollManager';
var scopes = [];
function pushScope(elem) {
@ -472,37 +474,38 @@ define(['dom', 'scrollManager'], function (dom, scrollManager) {
}
}
return {
autoFocus: autoFocus,
focus: focus,
focusableParent: focusableParent,
getFocusableElements: getFocusableElements,
moveLeft: function (sourceElement, options) {
var container = options ? options.container : null;
var focusableElements = options ? options.focusableElements : null;
nav(sourceElement, 0, container, focusableElements);
},
moveRight: function (sourceElement, options) {
var container = options ? options.container : null;
var focusableElements = options ? options.focusableElements : null;
nav(sourceElement, 1, container, focusableElements);
},
moveUp: function (sourceElement, options) {
var container = options ? options.container : null;
var focusableElements = options ? options.focusableElements : null;
nav(sourceElement, 2, container, focusableElements);
},
moveDown: function (sourceElement, options) {
var container = options ? options.container : null;
var focusableElements = options ? options.focusableElements : null;
nav(sourceElement, 3, container, focusableElements);
},
sendText: sendText,
isCurrentlyFocusable: isCurrentlyFocusable,
pushScope: pushScope,
popScope: popScope,
focusFirst: focusFirst,
focusLast: focusLast,
moveFocus: moveFocus
};
});
/* eslint-enable indent */
export default {
autoFocus: autoFocus,
focus: focus,
focusableParent: focusableParent,
getFocusableElements: getFocusableElements,
moveLeft: function (sourceElement, options) {
var container = options ? options.container : null;
var focusableElements = options ? options.focusableElements : null;
nav(sourceElement, 0, container, focusableElements);
},
moveRight: function (sourceElement, options) {
var container = options ? options.container : null;
var focusableElements = options ? options.focusableElements : null;
nav(sourceElement, 1, container, focusableElements);
},
moveUp: function (sourceElement, options) {
var container = options ? options.container : null;
var focusableElements = options ? options.focusableElements : null;
nav(sourceElement, 2, container, focusableElements);
},
moveDown: function (sourceElement, options) {
var container = options ? options.container : null;
var focusableElements = options ? options.focusableElements : null;
nav(sourceElement, 3, container, focusableElements);
},
sendText: sendText,
isCurrentlyFocusable: isCurrentlyFocusable,
pushScope: pushScope,
popScope: popScope,
focusFirst: focusFirst,
focusLast: focusLast,
moveFocus: moveFocus
};

View file

@ -4,6 +4,7 @@ define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager',
playbackManager = playbackManager.default || playbackManager;
browser = browser.default || browser;
loading = loading.default || loading;
focusManager = focusManager.default || focusManager;
function showViewSettings(instance) {
require(['guide-settings-dialog'], function (guideSettingsDialog) {

View file

@ -59,8 +59,8 @@ import 'css!./imageeditor';
currentItem = item;
apiClient.getRemoteImageProviders(getBaseRemoteOptions()).then(function (providers) {
const btnBrowseAllImages = page.querySelectorAll('.btnBrowseAllImages');
for (let i = 0, length = btnBrowseAllImages.length; i < length; i++) {
var btnBrowseAllImages = page.querySelectorAll('.btnBrowseAllImages');
for (var i = 0, length = btnBrowseAllImages.length; i < length; i++) {
if (providers.length) {
btnBrowseAllImages[i].classList.remove('hide');
} else {

View file

@ -5,8 +5,6 @@ import 'paper-icon-button-light';
import 'emby-button';
import 'css!./recordingfields';
/*eslint prefer-const: "error"*/
function onRecordingButtonClick(e) {
const item = this.item;

View file

@ -12,6 +12,8 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'c
function deleteTimer(apiClient, timerId) {
return new Promise(function (resolve, reject) {
require(['recordingHelper'], function (recordingHelper) {
recordingHelper = recordingHelper.default || recordingHelper;
recordingHelper.cancelTimerWithConfirmation(timerId, apiClient.serverId()).then(resolve, reject);
});
});

View file

@ -1,6 +1,7 @@
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';
recordingHelper = recordingHelper.default || recordingHelper;
loading = loading.default || loading;
function loadData(parent, program, apiClient) {

View file

@ -1,194 +1,195 @@
define(['globalize', 'loading', 'connectionManager'], function (globalize, loading, connectionManager) {
'use strict';
import globalize from 'globalize';
import loading from 'loading';
import connectionManager from 'connectionManager';
loading = loading.default || loading;
/*eslint prefer-const: "error"*/
function changeRecordingToSeries(apiClient, timerId, programId, confirmTimerCancellation) {
loading.show();
function changeRecordingToSeries(apiClient, timerId, programId, confirmTimerCancellation) {
loading.show();
return apiClient.getItem(apiClient.getCurrentUserId(), programId).then(function (item) {
if (item.IsSeries) {
// create series
return apiClient.getNewLiveTvTimerDefaults({ programId: programId }).then(function (timerDefaults) {
return apiClient.createLiveTvSeriesTimer(timerDefaults).then(function () {
loading.hide();
sendToast(globalize.translate('SeriesRecordingScheduled'));
return apiClient.getItem(apiClient.getCurrentUserId(), programId).then(function (item) {
if (item.IsSeries) {
// create series
return apiClient.getNewLiveTvTimerDefaults({ programId: programId }).then(function (timerDefaults) {
return apiClient.createLiveTvSeriesTimer(timerDefaults).then(function () {
loading.hide();
sendToast(globalize.translate('SeriesRecordingScheduled'));
});
});
} else {
// cancel
if (confirmTimerCancellation) {
return cancelTimerWithConfirmation(timerId, apiClient.serverId());
}
return cancelTimer(apiClient.serverId(), timerId, true);
}
});
}
function cancelTimerWithConfirmation(timerId, serverId) {
return new Promise(function (resolve, reject) {
import('confirm').then(({ default: confirm }) => {
confirm.default({
text: globalize.translate('MessageConfirmRecordingCancellation'),
primary: 'delete',
confirmText: globalize.translate('HeaderCancelRecording'),
cancelText: globalize.translate('HeaderKeepRecording')
}).then(function () {
loading.show();
const apiClient = connectionManager.getApiClient(serverId);
cancelTimer(apiClient, timerId, true).then(resolve, reject);
}, reject);
});
});
}
function cancelSeriesTimerWithConfirmation(timerId, serverId) {
return new Promise(function (resolve, reject) {
import('confirm').then(({ default: confirm }) => {
confirm.default({
text: globalize.translate('MessageConfirmRecordingCancellation'),
primary: 'delete',
confirmText: globalize.translate('HeaderCancelSeries'),
cancelText: globalize.translate('HeaderKeepSeries')
}).then(function () {
loading.show();
const apiClient = connectionManager.getApiClient(serverId);
apiClient.cancelLiveTvSeriesTimer(timerId).then(function () {
import('toast').then(({default: toast}) => {
toast(globalize.translate('SeriesCancelled'));
});
loading.hide();
resolve();
}, reject);
}, reject);
});
});
}
function cancelTimer(apiClient, timerId, hideLoading) {
loading.show();
return apiClient.cancelLiveTvTimer(timerId).then(function () {
if (hideLoading !== false) {
loading.hide();
sendToast(globalize.translate('RecordingCancelled'));
}
});
}
function createRecording(apiClient, programId, isSeries) {
loading.show();
return apiClient.getNewLiveTvTimerDefaults({ programId: programId }).then(function (item) {
const promise = isSeries ?
apiClient.createLiveTvSeriesTimer(item) :
apiClient.createLiveTvTimer(item);
return promise.then(function () {
loading.hide();
sendToast(globalize.translate('RecordingScheduled'));
});
});
}
function sendToast(msg) {
import('toast').then(({ default: toast }) => {
toast(msg);
});
}
function showMultiCancellationPrompt(serverId, programId, timerId, timerStatus, seriesTimerId) {
return new Promise(function (resolve, reject) {
import('dialog').then(({ default: dialog }) => {
const items = [];
items.push({
name: globalize.translate('HeaderKeepRecording'),
id: 'cancel',
type: 'submit'
});
if (timerStatus === 'InProgress') {
items.push({
name: globalize.translate('HeaderStopRecording'),
id: 'canceltimer',
type: 'cancel'
});
} else {
// cancel
if (confirmTimerCancellation) {
return cancelTimerWithConfirmation(timerId, apiClient.serverId());
}
return cancelTimer(apiClient.serverId(), timerId, true);
items.push({
name: globalize.translate('HeaderCancelRecording'),
id: 'canceltimer',
type: 'cancel'
});
}
});
}
function cancelTimerWithConfirmation(timerId, serverId) {
return new Promise(function (resolve, reject) {
require(['confirm'], function (confirm) {
confirm.default({
text: globalize.translate('MessageConfirmRecordingCancellation'),
primary: 'delete',
confirmText: globalize.translate('HeaderCancelRecording'),
cancelText: globalize.translate('HeaderKeepRecording')
}).then(function () {
loading.show();
var apiClient = connectionManager.getApiClient(serverId);
cancelTimer(apiClient, timerId, true).then(resolve, reject);
}, reject);
items.push({
name: globalize.translate('HeaderCancelSeries'),
id: 'cancelseriestimer',
type: 'cancel'
});
});
}
function cancelSeriesTimerWithConfirmation(timerId, serverId) {
return new Promise(function (resolve, reject) {
require(['confirm'], function (confirm) {
confirm.default({
dialog({
text: globalize.translate('MessageConfirmRecordingCancellation'),
primary: 'delete',
confirmText: globalize.translate('HeaderCancelSeries'),
cancelText: globalize.translate('HeaderKeepSeries')
text: globalize.translate('MessageConfirmRecordingCancellation'),
buttons: items
}).then(function () {
}).then(function (result) {
const apiClient = connectionManager.getApiClient(serverId);
if (result === 'canceltimer') {
loading.show();
var apiClient = connectionManager.getApiClient(serverId);
apiClient.cancelLiveTvSeriesTimer(timerId).then(function () {
require(['toast'], function (toast) {
cancelTimer(apiClient, timerId, true).then(resolve, reject);
} else if (result === 'cancelseriestimer') {
loading.show();
apiClient.cancelLiveTvSeriesTimer(seriesTimerId).then(function () {
import('toast').then(({ default: toast }) => {
toast(globalize.translate('SeriesCancelled'));
});
loading.hide();
resolve();
}, reject);
}, reject);
});
});
}
function cancelTimer(apiClient, timerId, hideLoading) {
loading.show();
return apiClient.cancelLiveTvTimer(timerId).then(function () {
if (hideLoading !== false) {
loading.hide();
sendToast(globalize.translate('RecordingCancelled'));
}
});
}
function createRecording(apiClient, programId, isSeries) {
loading.show();
return apiClient.getNewLiveTvTimerDefaults({ programId: programId }).then(function (item) {
var promise = isSeries ?
apiClient.createLiveTvSeriesTimer(item) :
apiClient.createLiveTvTimer(item);
return promise.then(function () {
loading.hide();
sendToast(globalize.translate('RecordingScheduled'));
});
});
}
function sendToast(msg) {
require(['toast'], function (toast) {
toast(msg);
});
}
function showMultiCancellationPrompt(serverId, programId, timerId, timerStatus, seriesTimerId) {
return new Promise(function (resolve, reject) {
require(['dialog'], function (dialog) {
var items = [];
items.push({
name: globalize.translate('HeaderKeepRecording'),
id: 'cancel',
type: 'submit'
});
if (timerStatus === 'InProgress') {
items.push({
name: globalize.translate('HeaderStopRecording'),
id: 'canceltimer',
type: 'cancel'
});
} else {
items.push({
name: globalize.translate('HeaderCancelRecording'),
id: 'canceltimer',
type: 'cancel'
});
resolve();
}
items.push({
name: globalize.translate('HeaderCancelSeries'),
id: 'cancelseriestimer',
type: 'cancel'
});
dialog({
text: globalize.translate('MessageConfirmRecordingCancellation'),
buttons: items
}).then(function (result) {
var apiClient = connectionManager.getApiClient(serverId);
if (result === 'canceltimer') {
loading.show();
cancelTimer(apiClient, timerId, true).then(resolve, reject);
} else if (result === 'cancelseriestimer') {
loading.show();
apiClient.cancelLiveTvSeriesTimer(seriesTimerId).then(function () {
require(['toast'], function (toast) {
toast(globalize.translate('SeriesCancelled'));
});
loading.hide();
resolve();
}, reject);
} else {
resolve();
}
}, reject);
});
}, reject);
});
}
});
}
function toggleRecording(serverId, programId, timerId, timerStatus, seriesTimerId) {
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();
}
function toggleRecording(serverId, programId, timerId, timerStatus, seriesTimerId) {
const apiClient = connectionManager.getApiClient(serverId);
const 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();
}
}
export default {
cancelTimer: cancelTimer,
createRecording: createRecording,
changeRecordingToSeries: changeRecordingToSeries,
toggleRecording: toggleRecording,
cancelTimerWithConfirmation: cancelTimerWithConfirmation,
cancelSeriesTimerWithConfirmation: cancelSeriesTimerWithConfirmation
};
return {
cancelTimer: cancelTimer,
createRecording: createRecording,
changeRecordingToSeries: changeRecordingToSeries,
toggleRecording: toggleRecording,
cancelTimerWithConfirmation: cancelTimerWithConfirmation,
cancelSeriesTimerWithConfirmation: cancelSeriesTimerWithConfirmation
};
});

View file

@ -1,143 +1,200 @@
define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'imageLoader', 'datetime', 'scrollStyles', 'emby-button', 'emby-checkbox', 'emby-input', 'emby-select', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'material-icons', 'flexStyles'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper, imageLoader, datetime) {
'use strict';
import dialogHelper from 'dialogHelper';
import globalize from 'globalize';
import layoutManager from 'layoutManager';
import connectionManager from 'connectionManager';
import loading from 'loading';
import scrollHelper from 'scrollHelper';
import datetime from 'datetime';
import 'scrollStyles';
import 'emby-button';
import 'emby-checkbox';
import 'emby-input';
import 'emby-select';
import 'paper-icon-button-light';
import 'css!./../formdialog';
import 'css!./recordingcreator';
import 'material-icons';
import 'flexStyles';
loading = loading.default || loading;
/*eslint prefer-const: "error"*/
var currentDialog;
var recordingUpdated = false;
var recordingDeleted = false;
var currentItemId;
var currentServerId;
let currentDialog;
let recordingUpdated = false;
let recordingDeleted = false;
let currentItemId;
let currentServerId;
function deleteTimer(apiClient, timerId) {
return new Promise(function (resolve, reject) {
require(['recordingHelper'], function (recordingHelper) {
recordingHelper.cancelSeriesTimerWithConfirmation(timerId, apiClient.serverId()).then(resolve, reject);
});
function deleteTimer(apiClient, timerId) {
return new Promise(function (resolve, reject) {
import('recordingHelper').then(({ default: recordingHelper }) => {
recordingHelper.cancelSeriesTimerWithConfirmation(timerId, apiClient.serverId()).then(resolve, reject);
});
});
}
function renderTimer(context, item) {
context.querySelector('#txtPrePaddingMinutes').value = item.PrePaddingSeconds / 60;
context.querySelector('#txtPostPaddingMinutes').value = item.PostPaddingSeconds / 60;
context.querySelector('.selectChannels').value = item.RecordAnyChannel ? 'all' : 'one';
context.querySelector('.selectAirTime').value = item.RecordAnyTime ? 'any' : 'original';
context.querySelector('.selectShowType').value = item.RecordNewOnly ? 'new' : 'all';
context.querySelector('.chkSkipEpisodesInLibrary').checked = item.SkipEpisodesInLibrary;
context.querySelector('.selectKeepUpTo').value = item.KeepUpTo || 0;
if (item.ChannelName || item.ChannelNumber) {
context.querySelector('.optionChannelOnly').innerHTML = globalize.translate('ChannelNameOnly', item.ChannelName || item.ChannelNumber);
} else {
context.querySelector('.optionChannelOnly').innerHTML = globalize.translate('OneChannel');
}
function renderTimer(context, item, apiClient) {
context.querySelector('#txtPrePaddingMinutes').value = item.PrePaddingSeconds / 60;
context.querySelector('#txtPostPaddingMinutes').value = item.PostPaddingSeconds / 60;
context.querySelector('.optionAroundTime').innerHTML = globalize.translate('AroundTime', datetime.getDisplayTime(datetime.parseISO8601Date(item.StartDate)));
context.querySelector('.selectChannels').value = item.RecordAnyChannel ? 'all' : 'one';
context.querySelector('.selectAirTime').value = item.RecordAnyTime ? 'any' : 'original';
loading.hide();
}
context.querySelector('.selectShowType').value = item.RecordNewOnly ? 'new' : 'all';
context.querySelector('.chkSkipEpisodesInLibrary').checked = item.SkipEpisodesInLibrary;
context.querySelector('.selectKeepUpTo').value = item.KeepUpTo || 0;
function closeDialog(isDeleted) {
recordingUpdated = true;
recordingDeleted = isDeleted;
if (item.ChannelName || item.ChannelNumber) {
context.querySelector('.optionChannelOnly').innerHTML = globalize.translate('ChannelNameOnly', item.ChannelName || item.ChannelNumber);
} else {
context.querySelector('.optionChannelOnly').innerHTML = globalize.translate('OneChannel');
}
dialogHelper.close(currentDialog);
}
context.querySelector('.optionAroundTime').innerHTML = globalize.translate('AroundTime', datetime.getDisplayTime(datetime.parseISO8601Date(item.StartDate)));
function onSubmit(e) {
const form = this;
const apiClient = connectionManager.getApiClient(currentServerId);
apiClient.getLiveTvSeriesTimer(currentItemId).then(function (item) {
item.PrePaddingSeconds = form.querySelector('#txtPrePaddingMinutes').value * 60;
item.PostPaddingSeconds = form.querySelector('#txtPostPaddingMinutes').value * 60;
item.RecordAnyChannel = form.querySelector('.selectChannels').value === 'all';
item.RecordAnyTime = form.querySelector('.selectAirTime').value === 'any';
item.RecordNewOnly = form.querySelector('.selectShowType').value === 'new';
item.SkipEpisodesInLibrary = form.querySelector('.chkSkipEpisodesInLibrary').checked;
item.KeepUpTo = form.querySelector('.selectKeepUpTo').value;
apiClient.updateLiveTvSeriesTimer(item);
});
e.preventDefault();
// Disable default form submission
return false;
}
function init(context) {
fillKeepUpTo(context);
context.querySelector('.btnCancel').addEventListener('click', function () {
closeDialog(false);
});
context.querySelector('.btnCancelRecording').addEventListener('click', function () {
const apiClient = connectionManager.getApiClient(currentServerId);
deleteTimer(apiClient, currentItemId).then(function () {
closeDialog(true);
});
});
context.querySelector('form').addEventListener('submit', onSubmit);
}
function reload(context, id) {
const apiClient = connectionManager.getApiClient(currentServerId);
loading.show();
if (typeof id === 'string') {
currentItemId = id;
apiClient.getLiveTvSeriesTimer(id).then(function (result) {
renderTimer(context, result);
loading.hide();
});
} else if (id) {
currentItemId = id.Id;
renderTimer(context, id);
loading.hide();
}
}
function closeDialog(isDeleted) {
recordingUpdated = true;
recordingDeleted = isDeleted;
function fillKeepUpTo(context) {
let html = '';
dialogHelper.close(currentDialog);
}
for (let i = 0; i <= 50; i++) {
let text;
function onSubmit(e) {
var form = this;
var apiClient = connectionManager.getApiClient(currentServerId);
apiClient.getLiveTvSeriesTimer(currentItemId).then(function (item) {
item.PrePaddingSeconds = form.querySelector('#txtPrePaddingMinutes').value * 60;
item.PostPaddingSeconds = form.querySelector('#txtPostPaddingMinutes').value * 60;
item.RecordAnyChannel = form.querySelector('.selectChannels').value === 'all';
item.RecordAnyTime = form.querySelector('.selectAirTime').value === 'any';
item.RecordNewOnly = form.querySelector('.selectShowType').value === 'new';
item.SkipEpisodesInLibrary = form.querySelector('.chkSkipEpisodesInLibrary').checked;
item.KeepUpTo = form.querySelector('.selectKeepUpTo').value;
apiClient.updateLiveTvSeriesTimer(item);
});
e.preventDefault();
// Disable default form submission
return false;
}
function init(context) {
fillKeepUpTo(context);
context.querySelector('.btnCancel').addEventListener('click', function () {
closeDialog(false);
});
context.querySelector('.btnCancelRecording').addEventListener('click', function () {
var apiClient = connectionManager.getApiClient(currentServerId);
deleteTimer(apiClient, currentItemId).then(function () {
closeDialog(true);
});
});
context.querySelector('form').addEventListener('submit', onSubmit);
}
function reload(context, id) {
var apiClient = connectionManager.getApiClient(currentServerId);
loading.show();
if (typeof id === 'string') {
currentItemId = id;
apiClient.getLiveTvSeriesTimer(id).then(function (result) {
renderTimer(context, result, apiClient);
loading.hide();
});
} else if (id) {
currentItemId = id.Id;
renderTimer(context, id, apiClient);
loading.hide();
}
}
function fillKeepUpTo(context) {
var html = '';
for (var i = 0; i <= 50; i++) {
var text;
if (i === 0) {
text = globalize.translate('AsManyAsPossible');
} else if (i === 1) {
text = globalize.translate('ValueOneEpisode');
} else {
text = globalize.translate('ValueEpisodeCount', i);
}
html += '<option value="' + i + '">' + text + '</option>';
if (i === 0) {
text = globalize.translate('AsManyAsPossible');
} else if (i === 1) {
text = globalize.translate('ValueOneEpisode');
} else {
text = globalize.translate('ValueEpisodeCount', i);
}
context.querySelector('.selectKeepUpTo').innerHTML = html;
html += '<option value="' + i + '">' + text + '</option>';
}
function onFieldChange(e) {
this.querySelector('.btnSubmit').click();
}
context.querySelector('.selectKeepUpTo').innerHTML = html;
}
function embed(itemId, serverId, options) {
function onFieldChange() {
this.querySelector('.btnSubmit').click();
}
function embed(itemId, serverId, options) {
recordingUpdated = false;
recordingDeleted = false;
currentServerId = serverId;
loading.show();
options = options || {};
import('text!./seriesrecordingeditor.template.html').then(({ default: template }) => {
const dialogOptions = {
removeOnClose: true,
scrollY: false
};
if (layoutManager.tv) {
dialogOptions.size = 'fullscreen';
} else {
dialogOptions.size = 'small';
}
const dlg = options.context;
dlg.classList.add('hide');
dlg.innerHTML = globalize.translateHtml(template, 'core');
dlg.querySelector('.formDialogHeader').classList.add('hide');
dlg.querySelector('.formDialogFooter').classList.add('hide');
dlg.querySelector('.formDialogContent').className = '';
dlg.querySelector('.dialogContentInner').className = '';
dlg.classList.remove('hide');
dlg.removeEventListener('change', onFieldChange);
dlg.addEventListener('change', onFieldChange);
currentDialog = dlg;
init(dlg);
reload(dlg, itemId);
});
}
function showEditor(itemId, serverId, options) {
return new Promise(function (resolve, reject) {
recordingUpdated = false;
recordingDeleted = false;
currentServerId = serverId;
loading.show();
options = options || {};
require(['text!./seriesrecordingeditor.template.html'], function (template) {
var dialogOptions = {
import('text!./seriesrecordingeditor.template.html').then(({ default: template }) => {
const dialogOptions = {
removeOnClose: true,
scrollY: false
};
@ -148,101 +205,58 @@ define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'c
dialogOptions.size = 'small';
}
var dlg = options.context;
const dlg = dialogHelper.createDialog(dialogOptions);
dlg.classList.add('hide');
dlg.innerHTML = globalize.translateHtml(template, 'core');
dlg.classList.add('formDialog');
dlg.classList.add('recordingDialog');
dlg.querySelector('.formDialogHeader').classList.add('hide');
dlg.querySelector('.formDialogFooter').classList.add('hide');
dlg.querySelector('.formDialogContent').className = '';
dlg.querySelector('.dialogContentInner').className = '';
dlg.classList.remove('hide');
if (!layoutManager.tv) {
dlg.style['min-width'] = '20%';
}
dlg.removeEventListener('change', onFieldChange);
dlg.addEventListener('change', onFieldChange);
let html = '';
html += globalize.translateHtml(template, 'core');
dlg.innerHTML = html;
if (options.enableCancel === false) {
dlg.querySelector('.formDialogFooter').classList.add('hide');
}
currentDialog = dlg;
dlg.addEventListener('closing', function () {
if (!recordingDeleted) {
this.querySelector('.btnSubmit').click();
}
});
dlg.addEventListener('close', function () {
if (recordingUpdated) {
resolve({
updated: true,
deleted: recordingDeleted
});
} else {
reject();
}
});
if (layoutManager.tv) {
scrollHelper.centerFocus.on(dlg.querySelector('.formDialogContent'), false);
}
init(dlg);
reload(dlg, itemId);
dialogHelper.open(dlg);
});
}
});
}
function showEditor(itemId, serverId, options) {
return new Promise(function (resolve, reject) {
recordingUpdated = false;
recordingDeleted = false;
currentServerId = serverId;
loading.show();
options = options || {};
require(['text!./seriesrecordingeditor.template.html'], function (template) {
var dialogOptions = {
removeOnClose: true,
scrollY: false
};
if (layoutManager.tv) {
dialogOptions.size = 'fullscreen';
} else {
dialogOptions.size = 'small';
}
var dlg = dialogHelper.createDialog(dialogOptions);
dlg.classList.add('formDialog');
dlg.classList.add('recordingDialog');
if (!layoutManager.tv) {
dlg.style['min-width'] = '20%';
}
var html = '';
html += globalize.translateHtml(template, 'core');
dlg.innerHTML = html;
if (options.enableCancel === false) {
dlg.querySelector('.formDialogFooter').classList.add('hide');
}
currentDialog = dlg;
dlg.addEventListener('closing', function () {
if (!recordingDeleted) {
this.querySelector('.btnSubmit').click();
}
});
dlg.addEventListener('close', function () {
if (recordingUpdated) {
resolve({
updated: true,
deleted: recordingDeleted
});
} else {
reject();
}
});
if (layoutManager.tv) {
scrollHelper.centerFocus.on(dlg.querySelector('.formDialogContent'), false);
}
init(dlg);
reload(dlg, itemId);
dialogHelper.open(dlg);
});
});
}
return {
show: showEditor,
embed: embed
};
});
export default {
show: showEditor,
embed: embed
};

View file

@ -6,6 +6,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
'use strict';
browser = browser.default || browser;
focusManager = focusManager.default || focusManager;
/**
* Name of transition event.

View file

@ -1,6 +1,8 @@
define(['require', 'dom', 'focusManager', 'dialogHelper', 'loading', 'layoutManager', 'connectionManager', 'globalize', 'userSettings', 'emby-select', 'paper-icon-button-light', 'material-icons', 'css!./../formdialog', 'emby-button', 'flexStyles'], function (require, dom, focusManager, dialogHelper, loading, layoutManager, connectionManager, globalize, userSettings) {
'use strict';
focusManager = focusManager.default || focusManager;
function onSubmit(e) {
e.preventDefault();
return false;

View file

@ -2,6 +2,7 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings',
'use strict';
loading = loading.default || loading;
focusManager = focusManager.default || focusManager;
var currentItem;
var hasChanges;

View file

@ -1,36 +1,34 @@
define(['css!./toast'], function () {
'use strict';
import 'css!./toast';
function remove(elem) {
setTimeout(function () {
elem.parentNode.removeChild(elem);
}, 300);
function remove(elem) {
setTimeout(function () {
elem.parentNode.removeChild(elem);
}, 300);
}
function animateRemove(elem) {
setTimeout(function () {
elem.classList.remove('toastVisible');
remove(elem);
}, 3300);
}
export default function (options) {
if (typeof options === 'string') {
options = {
text: options
};
}
function animateRemove(elem) {
setTimeout(function () {
elem.classList.remove('toastVisible');
remove(elem);
}, 3300);
}
const elem = document.createElement('div');
elem.classList.add('toast');
elem.innerHTML = options.text;
return function (options) {
if (typeof options === 'string') {
options = {
text: options
};
}
document.body.appendChild(elem);
var elem = document.createElement('div');
elem.classList.add('toast');
elem.innerHTML = options.text;
setTimeout(function () {
elem.classList.add('toastVisible');
document.body.appendChild(elem);
setTimeout(function () {
elem.classList.add('toastVisible');
animateRemove(elem);
}, 300);
};
});
animateRemove(elem);
}, 300);
}

View file

@ -3,6 +3,7 @@ define(['dialogHelper', 'dom', 'layoutManager', 'connectionManager', 'globalize'
browser = browser.default || browser;
loading = loading.default || loading;
focusManager = focusManager.default || focusManager;
var enableFocusTransform = !browser.slow && !browser.edge;

View file

@ -1,299 +1,304 @@
define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'listViewStyle', 'emby-input', 'emby-select', 'emby-button', 'flexStyles'], function ($, loading, globalize) {
'use strict';
import $ from 'jQuery';
import loading from 'loading';
import globalize from 'globalize';
import 'emby-checkbox';
import 'emby-input';
import 'listViewStyle';
import 'paper-icon-button-light';
import 'emby-select';
import 'emby-button';
import 'flexStyles';
loading = loading.default || loading;
export default function (page, providerId, options) {
function reload() {
loading.show();
ApiClient.getNamedConfiguration('livetv').then(function (config) {
const info = config.ListingProviders.filter(function (i) {
return i.Id === providerId;
})[0] || {};
listingsId = info.ListingsId;
$('#selectListing', page).val(info.ListingsId || '');
page.querySelector('.txtUser').value = info.Username || '';
page.querySelector('.txtPass').value = '';
page.querySelector('.txtZipCode').value = info.ZipCode || '';
return function (page, providerId, options) {
function reload() {
loading.show();
ApiClient.getNamedConfiguration('livetv').then(function (config) {
var info = config.ListingProviders.filter(function (i) {
return i.Id === providerId;
})[0] || {};
listingsId = info.ListingsId;
$('#selectListing', page).val(info.ListingsId || '');
page.querySelector('.txtUser').value = info.Username || '';
page.querySelector('.txtPass').value = '';
page.querySelector('.txtZipCode').value = info.ZipCode || '';
if (info.Username && info.Password) {
page.querySelector('.listingsSection').classList.remove('hide');
} else {
page.querySelector('.listingsSection').classList.add('hide');
}
page.querySelector('.chkAllTuners').checked = info.EnableAllTuners;
if (info.EnableAllTuners) {
page.querySelector('.selectTunersSection').classList.add('hide');
} else {
page.querySelector('.selectTunersSection').classList.remove('hide');
}
setCountry(info);
refreshTunerDevices(page, info, config.TunerHosts);
});
}
function setCountry(info) {
ApiClient.getJSON(ApiClient.getUrl('LiveTv/ListingProviders/SchedulesDirect/Countries')).then(function (result) {
var i;
var length;
var countryList = [];
for (var region in result) {
var countries = result[region];
if (countries.length && region !== 'ZZZ') {
for (i = 0, length = countries.length; i < length; i++) {
countryList.push({
name: countries[i].fullName,
value: countries[i].shortName
});
}
}
}
countryList.sort(function (a, b) {
if (a.name > b.name) {
return 1;
}
if (a.name < b.name) {
return -1;
}
return 0;
});
$('#selectCountry', page).html(countryList.map(function (c) {
return '<option value="' + c.value + '">' + c.name + '</option>';
}).join('')).val(info.Country || '');
$(page.querySelector('.txtZipCode')).trigger('change');
}, function () { // ApiClient.getJSON() error handler
Dashboard.alert({
message: globalize.translate('ErrorGettingTvLineups')
});
});
loading.hide();
}
function sha256(str) {
if (!self.TextEncoder) {
return Promise.resolve('');
if (info.Username && info.Password) {
page.querySelector('.listingsSection').classList.remove('hide');
} else {
page.querySelector('.listingsSection').classList.add('hide');
}
var buffer = new TextEncoder('utf-8').encode(str);
return crypto.subtle.digest('SHA-256', buffer).then(function (hash) {
return hex(hash);
});
}
page.querySelector('.chkAllTuners').checked = info.EnableAllTuners;
function hex(buffer) {
var hexCodes = [];
var view = new DataView(buffer);
for (var i = 0; i < view.byteLength; i += 4) {
var value = view.getUint32(i);
var stringValue = value.toString(16);
var paddedValue = ('00000000' + stringValue).slice(-'00000000'.length);
hexCodes.push(paddedValue);
if (info.EnableAllTuners) {
page.querySelector('.selectTunersSection').classList.add('hide');
} else {
page.querySelector('.selectTunersSection').classList.remove('hide');
}
return hexCodes.join('');
}
setCountry(info);
refreshTunerDevices(page, info, config.TunerHosts);
});
}
function submitLoginForm() {
loading.show();
sha256(page.querySelector('.txtPass').value).then(function (passwordHash) {
var info = {
Type: 'SchedulesDirect',
Username: page.querySelector('.txtUser').value,
EnableAllTuners: true,
Password: passwordHash,
Pw: page.querySelector('.txtPass').value
};
var id = providerId;
function setCountry(info) {
ApiClient.getJSON(ApiClient.getUrl('LiveTv/ListingProviders/SchedulesDirect/Countries')).then(function (result) {
let i;
let length;
const countryList = [];
if (id) {
info.Id = id;
for (const region in result) {
const countries = result[region];
if (countries.length && region !== 'ZZZ') {
for (i = 0, length = countries.length; i < length; i++) {
countryList.push({
name: countries[i].fullName,
value: countries[i].shortName
});
}
}
}
countryList.sort(function (a, b) {
if (a.name > b.name) {
return 1;
}
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('LiveTv/ListingProviders', {
ValidateLogin: true
}),
data: JSON.stringify(info),
contentType: 'application/json',
dataType: 'json'
}).then(function (result) {
Dashboard.processServerConfigurationUpdateResult();
providerId = result.Id;
reload();
}, function () {
Dashboard.alert({ // ApiClient.ajax() error handler
message: globalize.translate('ErrorSavingTvProvider')
});
});
if (a.name < b.name) {
return -1;
}
return 0;
});
$('#selectCountry', page).html(countryList.map(function (c) {
return '<option value="' + c.value + '">' + c.name + '</option>';
}).join('')).val(info.Country || '');
$(page.querySelector('.txtZipCode')).trigger('change');
}, function () { // ApiClient.getJSON() error handler
Dashboard.alert({
message: globalize.translate('ErrorGettingTvLineups')
});
});
loading.hide();
}
function sha256(str) {
if (!self.TextEncoder) {
return Promise.resolve('');
}
function submitListingsForm() {
var selectedListingsId = $('#selectListing', page).val();
const buffer = new TextEncoder('utf-8').encode(str);
return crypto.subtle.digest('SHA-256', buffer).then(function (hash) {
return hex(hash);
});
}
if (!selectedListingsId) {
return void Dashboard.alert({
message: globalize.translate('ErrorPleaseSelectLineup')
});
}
function hex(buffer) {
const hexCodes = [];
const view = new DataView(buffer);
loading.show();
var id = providerId;
ApiClient.getNamedConfiguration('livetv').then(function (config) {
var info = config.ListingProviders.filter(function (i) {
return i.Id === id;
})[0];
info.ZipCode = page.querySelector('.txtZipCode').value;
info.Country = $('#selectCountry', page).val();
info.ListingsId = selectedListingsId;
info.EnableAllTuners = page.querySelector('.chkAllTuners').checked;
info.EnabledTuners = info.EnableAllTuners ? [] : $('.chkTuner', page).get().filter(function (i) {
return i.checked;
}).map(function (i) {
return i.getAttribute('data-id');
});
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('LiveTv/ListingProviders', {
ValidateListings: true
}),
data: JSON.stringify(info),
contentType: 'application/json'
}).then(function (result) {
loading.hide();
if (options.showConfirmation) {
Dashboard.processServerConfigurationUpdateResult();
}
Events.trigger(self, 'submitted');
}, function () {
loading.hide();
Dashboard.alert({
message: globalize.translate('ErrorAddingListingsToSchedulesDirect')
});
});
});
for (let i = 0; i < view.byteLength; i += 4) {
const value = view.getUint32(i);
const stringValue = value.toString(16);
const paddedValue = ('00000000' + stringValue).slice(-'00000000'.length);
hexCodes.push(paddedValue);
}
function refreshListings(value) {
if (!value) {
return void $('#selectListing', page).html('');
return hexCodes.join('');
}
function submitLoginForm() {
loading.show();
sha256(page.querySelector('.txtPass').value).then(function (passwordHash) {
const info = {
Type: 'SchedulesDirect',
Username: page.querySelector('.txtUser').value,
EnableAllTuners: true,
Password: passwordHash,
Pw: page.querySelector('.txtPass').value
};
const id = providerId;
if (id) {
info.Id = id;
}
loading.show();
ApiClient.ajax({
type: 'GET',
url: ApiClient.getUrl('LiveTv/ListingProviders/Lineups', {
Id: providerId,
Location: value,
Country: $('#selectCountry', page).val()
type: 'POST',
url: ApiClient.getUrl('LiveTv/ListingProviders', {
ValidateLogin: true
}),
data: JSON.stringify(info),
contentType: 'application/json',
dataType: 'json'
}).then(function (result) {
$('#selectListing', page).html(result.map(function (o) {
return '<option value="' + o.Id + '">' + o.Name + '</option>';
}));
if (listingsId) {
$('#selectListing', page).val(listingsId);
}
loading.hide();
}, function (result) {
Dashboard.alert({
message: globalize.translate('ErrorGettingTvLineups')
Dashboard.processServerConfigurationUpdateResult();
providerId = result.Id;
reload();
}, function () {
Dashboard.alert({ // ApiClient.ajax() error handler
message: globalize.translate('ErrorSavingTvProvider')
});
refreshListings('');
});
});
}
function submitListingsForm() {
const selectedListingsId = $('#selectListing', page).val();
if (!selectedListingsId) {
return void Dashboard.alert({
message: globalize.translate('ErrorPleaseSelectLineup')
});
}
loading.show();
const id = providerId;
ApiClient.getNamedConfiguration('livetv').then(function (config) {
const info = config.ListingProviders.filter(function (i) {
return i.Id === id;
})[0];
info.ZipCode = page.querySelector('.txtZipCode').value;
info.Country = $('#selectCountry', page).val();
info.ListingsId = selectedListingsId;
info.EnableAllTuners = page.querySelector('.chkAllTuners').checked;
info.EnabledTuners = info.EnableAllTuners ? [] : $('.chkTuner', page).get().filter(function (i) {
return i.checked;
}).map(function (i) {
return i.getAttribute('data-id');
});
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('LiveTv/ListingProviders', {
ValidateListings: true
}),
data: JSON.stringify(info),
contentType: 'application/json'
}).then(function (result) {
loading.hide();
});
}
function getTunerName(providerId) {
switch (providerId = providerId.toLowerCase()) {
case 'm3u':
return 'M3U Playlist';
case 'hdhomerun':
return 'HDHomerun';
case 'satip':
return 'DVB';
default:
return 'Unknown';
}
}
function refreshTunerDevices(page, providerInfo, devices) {
var html = '';
for (var i = 0, length = devices.length; i < length; i++) {
var device = devices[i];
html += '<div class="listItem">';
var enabledTuners = providerInfo.EnabledTuners || [];
var isChecked = providerInfo.EnableAllTuners || enabledTuners.indexOf(device.Id) !== -1;
var checkedAttribute = isChecked ? ' checked' : '';
html += '<label class="checkboxContainer listItemCheckboxContainer"><input type="checkbox" is="emby-checkbox" data-id="' + device.Id + '" class="chkTuner" ' + checkedAttribute + '/><span></span></label>';
html += '<div class="listItemBody two-line">';
html += '<div class="listItemBodyText">';
html += device.FriendlyName || getTunerName(device.Type);
html += '</div>';
html += '<div class="listItemBodyText secondary">';
html += device.Url;
html += '</div>';
html += '</div>';
html += '</div>';
}
page.querySelector('.tunerList').innerHTML = html;
}
var listingsId;
var self = this;
self.submit = function () {
page.querySelector('.btnSubmitListingsContainer').click();
};
self.init = function () {
options = options || {};
// Only hide the buttons if explicitly set to false; default to showing if undefined or null
// FIXME: rename this option to clarify logic
var hideCancelButton = options.showCancelButton === false;
page.querySelector('.btnCancel').classList.toggle('hide', hideCancelButton);
var hideSubmitButton = options.showSubmitButton === false;
page.querySelector('.btnSubmitListings').classList.toggle('hide', hideSubmitButton);
$('.formLogin', page).on('submit', function () {
submitLoginForm();
return false;
});
$('.formListings', page).on('submit', function () {
submitListingsForm();
return false;
});
$('.txtZipCode', page).on('change', function () {
refreshListings(this.value);
});
page.querySelector('.chkAllTuners').addEventListener('change', function (e) {
if (e.target.checked) {
page.querySelector('.selectTunersSection').classList.add('hide');
} else {
page.querySelector('.selectTunersSection').classList.remove('hide');
if (options.showConfirmation) {
Dashboard.processServerConfigurationUpdateResult();
}
Events.trigger(self, 'submitted');
}, function () {
loading.hide();
Dashboard.alert({
message: globalize.translate('ErrorAddingListingsToSchedulesDirect')
});
});
$('.createAccountHelp', page).html(globalize.translate('MessageCreateAccountAt', '<a is="emby-linkbutton" class="button-link" href="http://www.schedulesdirect.org" target="_blank">http://www.schedulesdirect.org</a>'));
reload();
};
});
}
function refreshListings(value) {
if (!value) {
return void $('#selectListing', page).html('');
}
loading.show();
ApiClient.ajax({
type: 'GET',
url: ApiClient.getUrl('LiveTv/ListingProviders/Lineups', {
Id: providerId,
Location: value,
Country: $('#selectCountry', page).val()
}),
dataType: 'json'
}).then(function (result) {
$('#selectListing', page).html(result.map(function (o) {
return '<option value="' + o.Id + '">' + o.Name + '</option>';
}));
if (listingsId) {
$('#selectListing', page).val(listingsId);
}
loading.hide();
}, function (result) {
Dashboard.alert({
message: globalize.translate('ErrorGettingTvLineups')
});
refreshListings('');
loading.hide();
});
}
function getTunerName(providerId) {
switch (providerId = providerId.toLowerCase()) {
case 'm3u':
return 'M3U Playlist';
case 'hdhomerun':
return 'HDHomerun';
case 'satip':
return 'DVB';
default:
return 'Unknown';
}
}
function refreshTunerDevices(page, providerInfo, devices) {
let html = '';
for (let i = 0, length = devices.length; i < length; i++) {
const device = devices[i];
html += '<div class="listItem">';
const enabledTuners = providerInfo.EnabledTuners || [];
const isChecked = providerInfo.EnableAllTuners || enabledTuners.indexOf(device.Id) !== -1;
const checkedAttribute = isChecked ? ' checked' : '';
html += '<label class="checkboxContainer listItemCheckboxContainer"><input type="checkbox" is="emby-checkbox" data-id="' + device.Id + '" class="chkTuner" ' + checkedAttribute + '/><span></span></label>';
html += '<div class="listItemBody two-line">';
html += '<div class="listItemBodyText">';
html += device.FriendlyName || getTunerName(device.Type);
html += '</div>';
html += '<div class="listItemBodyText secondary">';
html += device.Url;
html += '</div>';
html += '</div>';
html += '</div>';
}
page.querySelector('.tunerList').innerHTML = html;
}
let listingsId;
const self = this;
self.submit = function () {
page.querySelector('.btnSubmitListingsContainer').click();
};
});
self.init = function () {
options = options || {};
// Only hide the buttons if explicitly set to false; default to showing if undefined or null
// FIXME: rename this option to clarify logic
const hideCancelButton = options.showCancelButton === false;
page.querySelector('.btnCancel').classList.toggle('hide', hideCancelButton);
const hideSubmitButton = options.showSubmitButton === false;
page.querySelector('.btnSubmitListings').classList.toggle('hide', hideSubmitButton);
$('.formLogin', page).on('submit', function () {
submitLoginForm();
return false;
});
$('.formListings', page).on('submit', function () {
submitListingsForm();
return false;
});
$('.txtZipCode', page).on('change', function () {
refreshListings(this.value);
});
page.querySelector('.chkAllTuners').addEventListener('change', function (e) {
if (e.target.checked) {
page.querySelector('.selectTunersSection').classList.add('hide');
} else {
page.querySelector('.selectTunersSection').classList.remove('hide');
}
});
$('.createAccountHelp', page).html(globalize.translate('MessageCreateAccountAt', '<a is="emby-linkbutton" class="button-link" href="http://www.schedulesdirect.org" target="_blank">http://www.schedulesdirect.org</a>'));
reload();
};
}

View file

@ -1,191 +1,193 @@
define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'emby-input', 'listViewStyle', 'paper-icon-button-light'], function ($, loading, globalize) {
'use strict';
import $ from 'jQuery';
import loading from 'loading';
import globalize from 'globalize';
import 'emby-checkbox';
import 'emby-input';
import 'listViewStyle';
import 'paper-icon-button-light';
loading = loading.default || loading;
export default function (page, providerId, options) {
function getListingProvider(config, id) {
if (config && id) {
const result = config.ListingProviders.filter(function (provider) {
return provider.Id === id;
})[0];
return function (page, providerId, options) {
function getListingProvider(config, id) {
if (config && id) {
var result = config.ListingProviders.filter(function (provider) {
return provider.Id === id;
})[0];
if (result) {
return Promise.resolve(result);
}
return getListingProvider();
if (result) {
return Promise.resolve(result);
}
return ApiClient.getJSON(ApiClient.getUrl('LiveTv/ListingProviders/Default'));
return getListingProvider();
}
function reload() {
loading.show();
ApiClient.getNamedConfiguration('livetv').then(function (config) {
getListingProvider(config, providerId).then(function (info) {
page.querySelector('.txtPath').value = info.Path || '';
page.querySelector('.txtKids').value = (info.KidsCategories || []).join('|');
page.querySelector('.txtNews').value = (info.NewsCategories || []).join('|');
page.querySelector('.txtSports').value = (info.SportsCategories || []).join('|');
page.querySelector('.txtMovies').value = (info.MovieCategories || []).join('|');
page.querySelector('.txtMoviePrefix').value = info.MoviePrefix || '';
page.querySelector('.txtUserAgent').value = info.UserAgent || '';
page.querySelector('.chkAllTuners').checked = info.EnableAllTuners;
return ApiClient.getJSON(ApiClient.getUrl('LiveTv/ListingProviders/Default'));
}
if (page.querySelector('.chkAllTuners').checked) {
page.querySelector('.selectTunersSection').classList.add('hide');
} else {
page.querySelector('.selectTunersSection').classList.remove('hide');
}
function reload() {
loading.show();
ApiClient.getNamedConfiguration('livetv').then(function (config) {
getListingProvider(config, providerId).then(function (info) {
page.querySelector('.txtPath').value = info.Path || '';
page.querySelector('.txtKids').value = (info.KidsCategories || []).join('|');
page.querySelector('.txtNews').value = (info.NewsCategories || []).join('|');
page.querySelector('.txtSports').value = (info.SportsCategories || []).join('|');
page.querySelector('.txtMovies').value = (info.MovieCategories || []).join('|');
page.querySelector('.txtMoviePrefix').value = info.MoviePrefix || '';
page.querySelector('.txtUserAgent').value = info.UserAgent || '';
page.querySelector('.chkAllTuners').checked = info.EnableAllTuners;
refreshTunerDevices(page, info, config.TunerHosts);
loading.hide();
});
});
}
function getCategories(txtInput) {
var value = txtInput.value;
if (value) {
return value.split('|');
}
return [];
}
function submitListingsForm() {
loading.show();
var id = providerId;
ApiClient.getNamedConfiguration('livetv').then(function (config) {
var info = config.ListingProviders.filter(function (provider) {
return provider.Id === id;
})[0] || {};
info.Type = 'xmltv';
info.Path = page.querySelector('.txtPath').value;
info.MoviePrefix = page.querySelector('.txtMoviePrefix').value || null;
info.UserAgent = page.querySelector('.txtUserAgent').value || null;
info.MovieCategories = getCategories(page.querySelector('.txtMovies'));
info.KidsCategories = getCategories(page.querySelector('.txtKids'));
info.NewsCategories = getCategories(page.querySelector('.txtNews'));
info.SportsCategories = getCategories(page.querySelector('.txtSports'));
info.EnableAllTuners = page.querySelector('.chkAllTuners').checked;
info.EnabledTuners = info.EnableAllTuners ? [] : $('.chkTuner', page).get().filter(function (tuner) {
return tuner.checked;
}).map(function (tuner) {
return tuner.getAttribute('data-id');
});
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('LiveTv/ListingProviders', {
ValidateListings: true
}),
data: JSON.stringify(info),
contentType: 'application/json'
}).then(function (result) {
loading.hide();
if (options.showConfirmation !== false) {
Dashboard.processServerConfigurationUpdateResult();
}
Events.trigger(self, 'submitted');
}, function () {
loading.hide();
Dashboard.alert({
message: globalize.translate('ErrorAddingXmlTvFile')
});
});
});
}
function getTunerName(providerId) {
switch (providerId = providerId.toLowerCase()) {
case 'm3u':
return 'M3U Playlist';
case 'hdhomerun':
return 'HDHomerun';
case 'satip':
return 'DVB';
default:
return 'Unknown';
}
}
function refreshTunerDevices(page, providerInfo, devices) {
var html = '';
for (var i = 0, length = devices.length; i < length; i++) {
var device = devices[i];
html += '<div class="listItem">';
var enabledTuners = providerInfo.EnabledTuners || [];
var isChecked = providerInfo.EnableAllTuners || enabledTuners.indexOf(device.Id) !== -1;
var checkedAttribute = isChecked ? ' checked' : '';
html += '<label class="listItemCheckboxContainer"><input type="checkbox" is="emby-checkbox" class="chkTuner" data-id="' + device.Id + '" ' + checkedAttribute + '><span></span></label>';
html += '<div class="listItemBody two-line">';
html += '<div class="listItemBodyText">';
html += device.FriendlyName || getTunerName(device.Type);
html += '</div>';
html += '<div class="listItemBodyText secondary">';
html += device.Url;
html += '</div>';
html += '</div>';
html += '</div>';
}
page.querySelector('.tunerList').innerHTML = html;
}
function onSelectPathClick(e) {
var page = $(e.target).parents('.xmltvForm')[0];
require(['directorybrowser'], function (directoryBrowser) {
var picker = new directoryBrowser.default();
picker.show({
includeFiles: true,
callback: function (path) {
if (path) {
var txtPath = page.querySelector('.txtPath');
txtPath.value = path;
txtPath.focus();
}
picker.close();
}
});
});
}
var self = this;
self.submit = function () {
page.querySelector('.btnSubmitListings').click();
};
self.init = function () {
options = options || {};
// Only hide the buttons if explicitly set to false; default to showing if undefined or null
// FIXME: rename this option to clarify logic
var hideCancelButton = options.showCancelButton === false;
page.querySelector('.btnCancel').classList.toggle('hide', hideCancelButton);
var hideSubmitButton = options.showSubmitButton === false;
page.querySelector('.btnSubmitListings').classList.toggle('hide', hideSubmitButton);
$('form', page).on('submit', function () {
submitListingsForm();
return false;
});
page.querySelector('#btnSelectPath').addEventListener('click', onSelectPathClick);
page.querySelector('.chkAllTuners').addEventListener('change', function (evt) {
if (evt.target.checked) {
if (page.querySelector('.chkAllTuners').checked) {
page.querySelector('.selectTunersSection').classList.add('hide');
} else {
page.querySelector('.selectTunersSection').classList.remove('hide');
}
refreshTunerDevices(page, info, config.TunerHosts);
loading.hide();
});
reload();
};
});
}
function getCategories(txtInput) {
const value = txtInput.value;
if (value) {
return value.split('|');
}
return [];
}
function submitListingsForm() {
loading.show();
const id = providerId;
ApiClient.getNamedConfiguration('livetv').then(function (config) {
const info = config.ListingProviders.filter(function (provider) {
return provider.Id === id;
})[0] || {};
info.Type = 'xmltv';
info.Path = page.querySelector('.txtPath').value;
info.MoviePrefix = page.querySelector('.txtMoviePrefix').value || null;
info.UserAgent = page.querySelector('.txtUserAgent').value || null;
info.MovieCategories = getCategories(page.querySelector('.txtMovies'));
info.KidsCategories = getCategories(page.querySelector('.txtKids'));
info.NewsCategories = getCategories(page.querySelector('.txtNews'));
info.SportsCategories = getCategories(page.querySelector('.txtSports'));
info.EnableAllTuners = page.querySelector('.chkAllTuners').checked;
info.EnabledTuners = info.EnableAllTuners ? [] : $('.chkTuner', page).get().filter(function (tuner) {
return tuner.checked;
}).map(function (tuner) {
return tuner.getAttribute('data-id');
});
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('LiveTv/ListingProviders', {
ValidateListings: true
}),
data: JSON.stringify(info),
contentType: 'application/json'
}).then(function (result) {
loading.hide();
if (options.showConfirmation !== false) {
Dashboard.processServerConfigurationUpdateResult();
}
Events.trigger(self, 'submitted');
}, function () {
loading.hide();
Dashboard.alert({
message: globalize.translate('ErrorAddingXmlTvFile')
});
});
});
}
function getTunerName(providerId) {
switch (providerId = providerId.toLowerCase()) {
case 'm3u':
return 'M3U Playlist';
case 'hdhomerun':
return 'HDHomerun';
case 'satip':
return 'DVB';
default:
return 'Unknown';
}
}
function refreshTunerDevices(page, providerInfo, devices) {
let html = '';
for (let i = 0, length = devices.length; i < length; i++) {
const device = devices[i];
html += '<div class="listItem">';
const enabledTuners = providerInfo.EnabledTuners || [];
const isChecked = providerInfo.EnableAllTuners || enabledTuners.indexOf(device.Id) !== -1;
const checkedAttribute = isChecked ? ' checked' : '';
html += '<label class="listItemCheckboxContainer"><input type="checkbox" is="emby-checkbox" class="chkTuner" data-id="' + device.Id + '" ' + checkedAttribute + '><span></span></label>';
html += '<div class="listItemBody two-line">';
html += '<div class="listItemBodyText">';
html += device.FriendlyName || getTunerName(device.Type);
html += '</div>';
html += '<div class="listItemBodyText secondary">';
html += device.Url;
html += '</div>';
html += '</div>';
html += '</div>';
}
page.querySelector('.tunerList').innerHTML = html;
}
function onSelectPathClick(e) {
const page = $(e.target).parents('.xmltvForm')[0];
import('directorybrowser').then(({default: directoryBrowser}) => {
const picker = new directoryBrowser();
picker.show({
includeFiles: true,
callback: function (path) {
if (path) {
const txtPath = page.querySelector('.txtPath');
txtPath.value = path;
txtPath.focus();
}
picker.close();
}
});
});
}
const self = this;
self.submit = function () {
page.querySelector('.btnSubmitListings').click();
};
});
self.init = function () {
options = options || {};
// Only hide the buttons if explicitly set to false; default to showing if undefined or null
// FIXME: rename this option to clarify logic
const hideCancelButton = options.showCancelButton === false;
page.querySelector('.btnCancel').classList.toggle('hide', hideCancelButton);
const hideSubmitButton = options.showSubmitButton === false;
page.querySelector('.btnSubmitListings').classList.toggle('hide', hideSubmitButton);
$('form', page).on('submit', function () {
submitListingsForm();
return false;
});
page.querySelector('#btnSelectPath').addEventListener('click', onSelectPathClick);
page.querySelector('.chkAllTuners').addEventListener('change', function (evt) {
if (evt.target.checked) {
page.querySelector('.selectTunersSection').classList.add('hide');
} else {
page.querySelector('.selectTunersSection').classList.remove('hide');
}
});
reload();
};
}

View file

@ -1,9 +1,19 @@
define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'layoutManager', 'focusManager', 'globalize', 'itemHelper', 'css!./upnextdialog', 'emby-button', 'flexStyles'], function (dom, playbackManager, connectionManager, events, mediaInfo, layoutManager, focusManager, globalize, itemHelper) {
'use strict';
import dom from 'dom';
import playbackManager from 'playbackManager';
import connectionManager from 'connectionManager';
import events from 'events';
import mediaInfo from 'mediaInfo';
import layoutManager from 'layoutManager';
import focusManager from 'focusManager';
import globalize from 'globalize';
import itemHelper from 'itemHelper';
import 'css!./upnextdialog';
import 'emby-button';
import 'flexStyles';
playbackManager = playbackManager.default || playbackManager;
/* eslint-disable indent */
var transitionEndEventName = dom.whichTransitionEvent();
const transitionEndEventName = dom.whichTransitionEvent();
function seriesImageUrl(item, options) {
if (item.Type !== 'Episode') {
@ -58,7 +68,7 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
function setPoster(osdPoster, item, secondaryItem) {
if (item) {
var imgUrl = seriesImageUrl(item, { type: 'Primary' }) ||
let imgUrl = seriesImageUrl(item, { type: 'Primary' }) ||
seriesImageUrl(item, { type: 'Thumb' }) ||
imageUrl(item, { type: 'Primary' });
@ -78,7 +88,7 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
}
function getHtml() {
var html = '';
let html = '';
html += '<div class="upNextDialog-poster">';
html += '</div>';
@ -114,17 +124,17 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
}
function setNextVideoText() {
var instance = this;
const instance = this;
var elem = instance.options.parent;
const elem = instance.options.parent;
var secondsRemaining = Math.max(Math.round(getTimeRemainingMs(instance) / 1000), 0);
const secondsRemaining = Math.max(Math.round(getTimeRemainingMs(instance) / 1000), 0);
console.debug('up next seconds remaining: ' + secondsRemaining);
var timeText = '<span class="upNextDialog-countdownText">' + globalize.translate('HeaderSecondsValue', secondsRemaining) + '</span>';
const timeText = '<span class="upNextDialog-countdownText">' + globalize.translate('HeaderSecondsValue', secondsRemaining) + '</span>';
var nextVideoText = instance.itemType === 'Episode' ?
const nextVideoText = instance.itemType === 'Episode' ?
globalize.translate('HeaderNextEpisodePlayingInValue', timeText) :
globalize.translate('HeaderNextVideoPlayingInValue', timeText);
@ -132,9 +142,9 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
}
function fillItem(item) {
var instance = this;
const instance = this;
var elem = instance.options.parent;
const elem = instance.options.parent;
setPoster(elem.querySelector('.upNextDialog-poster'), item);
@ -143,7 +153,7 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
elem.querySelector('.upNextDialog-mediainfo').innerHTML = mediaInfo.getPrimaryMediaInfoHtml(item, {
});
var title = itemHelper.getDisplayName(item);
let title = itemHelper.getDisplayName(item);
if (item.SeriesName) {
title = item.SeriesName + ' - ' + title;
}
@ -163,10 +173,10 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
}
function onStartNowClick() {
var options = this.options;
const options = this.options;
if (options) {
var player = options.player;
const player = options.player;
this.hide();
@ -188,7 +198,7 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
}
function clearHideAnimationEventListeners(instance, elem) {
var fn = instance._onHideAnimationComplete;
const fn = instance._onHideAnimationComplete;
if (fn) {
dom.removeEventListener(elem, transitionEndEventName, fn, {
@ -198,8 +208,8 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
}
function onHideAnimationComplete(e) {
var instance = this;
var elem = e.target;
const instance = this;
const elem = e.target;
elem.classList.add('hide');
@ -208,14 +218,14 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
}
function hideComingUpNext() {
var instance = this;
const instance = this;
clearCountdownTextTimeout(this);
if (!instance.options) {
return;
}
var elem = instance.options.parent;
const elem = instance.options.parent;
if (!elem) {
return;
@ -232,7 +242,7 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
elem.classList.add('upNextDialog-hidden');
var fn = onHideAnimationComplete.bind(instance);
const fn = onHideAnimationComplete.bind(instance);
instance._onHideAnimationComplete = fn;
dom.addEventListener(elem, transitionEndEventName, fn, {
@ -241,12 +251,12 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
}
function getTimeRemainingMs(instance) {
var options = instance.options;
const options = instance.options;
if (options) {
var runtimeTicks = playbackManager.duration(options.player);
const runtimeTicks = playbackManager.duration(options.player);
if (runtimeTicks) {
var timeRemainingTicks = runtimeTicks - playbackManager.currentTime(options.player);
const timeRemainingTicks = runtimeTicks - playbackManager.currentTime(options.player);
return Math.round(timeRemainingTicks / 10000);
}
@ -256,7 +266,7 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
}
function startComingUpNextHideTimer(instance) {
var timeRemainingMs = getTimeRemainingMs(instance);
const timeRemainingMs = getTimeRemainingMs(instance);
if (timeRemainingMs <= 0) {
return;
@ -268,14 +278,14 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
instance._countdownTextTimeout = setInterval(setNextVideoText.bind(instance), 400);
}
function UpNextDialog(options) {
class UpNextDialog {
constructor(options) {
this.options = options;
init(this, options);
}
UpNextDialog.prototype.show = function () {
var elem = this.options.parent;
show() {
const elem = this.options.parent;
clearHideAnimationEventListeners(this, elem);
@ -293,18 +303,18 @@ define(['dom', 'playbackManager', 'connectionManager', 'events', 'mediaInfo', 'l
}
startComingUpNextHideTimer(this);
};
UpNextDialog.prototype.hide = function () {
}
hide() {
hideComingUpNext.call(this);
};
UpNextDialog.prototype.destroy = function () {
}
destroy() {
hideComingUpNext.call(this);
this.options = null;
this.itemType = null;
};
}
}
return UpNextDialog;
});
export default UpNextDialog;
/* eslint-enable indent */

View file

@ -1,6 +1,8 @@
define(['viewContainer', 'focusManager', 'queryString', 'layoutManager'], function (viewContainer, focusManager, queryString, layoutManager) {
'use strict';
focusManager = focusManager.default || focusManager;
var currentView;
var dispatchPageEvents;