Merge branch 'master' into titles

This commit is contained in:
dkanada 2020-08-02 16:57:13 +09:00 committed by GitHub
commit 54eab501c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 705 additions and 655 deletions

View file

@ -1,6 +1,8 @@
define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdrop', 'browser', 'page', 'appSettings', 'apphost', 'connectionManager'], function (loading, globalize, events, viewManager, skinManager, backdrop, browser, page, appSettings, appHost, connectionManager) {
'use strict';
loading = loading.default || loading;
var appRouter = {
showLocalLogin: function (serverId, manualLogin) {
var pageName = manualLogin ? 'manuallogin' : 'login';

View file

@ -1,5 +1,14 @@
define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoader', 'globalize', 'layoutManager', 'scrollStyles', 'emby-itemscontainer'], function (loading, libraryBrowser, cardBuilder, dom, appHost, imageLoader, globalize, layoutManager) {
'use strict';
import loading from 'loading';
import cardBuilder from 'cardBuilder';
import dom from 'dom';
import appHost from 'apphost';
import imageLoader from 'imageLoader';
import globalize from 'globalize';
import layoutManager from 'layoutManager';
import 'scrollStyles';
import 'emby-itemscontainer';
/* eslint-disable indent */
function enableScrollX() {
return !layoutManager.desktop;
@ -94,8 +103,8 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad
}
function loadSection(elem, userId, topParentId, section, isSingleSection) {
var screenWidth = dom.getWindowSize().innerWidth;
var options = {
const screenWidth = dom.getWindowSize().innerWidth;
const options = {
SortBy: 'SortName',
SortOrder: 'Ascending',
Filters: 'IsFavorite',
@ -118,7 +127,7 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad
}
}
var promise;
let promise;
if (section.types === 'MusicArtist') {
promise = ApiClient.getArtists(userId, options);
@ -128,7 +137,7 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad
}
return promise.then(function (result) {
var html = '';
let html = '';
if (result.Items.length) {
if (html += '<div class="sectionTitleContainer sectionTitleContainer-cards padded-left">', !layoutManager.tv && options.Limit && result.Items.length >= options.Limit) {
@ -144,7 +153,7 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad
html += '</div>';
if (enableScrollX()) {
var scrollXClass = 'scrollX hiddenScrollX';
let scrollXClass = 'scrollX hiddenScrollX';
if (layoutManager.tv) {
scrollXClass += ' smoothScrollX';
}
@ -154,7 +163,7 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad
html += '<div is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right">';
}
var cardLayout = appHost.preferVisualCards && section.autoCardLayout && section.showTitle;
let cardLayout = appHost.preferVisualCards && section.autoCardLayout && section.showTitle;
cardLayout = false;
html += cardBuilder.getCardsHtml(result.Items, {
preferThumb: section.preferThumb,
@ -179,10 +188,10 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad
});
}
function loadSections(page, userId, topParentId, types) {
export function loadSections(page, userId, topParentId, types) {
loading.show();
var sections = getSections();
var sectionid = getParameterByName('sectionid');
let sections = getSections();
const sectionid = getParameterByName('sectionid');
if (sectionid) {
sections = sections.filter(function (s) {
@ -196,24 +205,22 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad
});
}
var i;
var length;
var elem = page.querySelector('.favoriteSections');
let elem = page.querySelector('.favoriteSections');
if (!elem.innerHTML) {
var html = '';
let html = '';
for (i = 0, length = sections.length; i < length; i++) {
for (let i = 0, length = sections.length; i < length; i++) {
html += '<div class="verticalSection section' + sections[i].id + '"></div>';
}
elem.innerHTML = html;
}
var promises = [];
const promises = [];
for (i = 0, length = sections.length; i < length; i++) {
var section = sections[i];
for (let i = 0, length = sections.length; i < length; i++) {
const section = sections[i];
elem = page.querySelector('.section' + section.id);
promises.push(loadSection(elem, userId, topParentId, section, sections.length === 1));
}
@ -223,7 +230,8 @@ define(['loading', 'libraryBrowser', 'cardBuilder', 'dom', 'apphost', 'imageLoad
});
}
return {
render: loadSections
};
});
export default {
render: loadSections
};
/* eslint-enable indent */

View file

@ -1,6 +1,8 @@
define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-programcell', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'webcomponents'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) {
'use strict';
loading = loading.default || loading;
function showViewSettings(instance) {
require(['guide-settings-dialog'], function (guideSettingsDialog) {
guideSettingsDialog.show(instance.categoryOptions).then(function () {

View file

@ -19,6 +19,8 @@ import 'css!./imageeditor';
const enableFocusTransform = !browser.slow && !browser.edge;
loading = loading.default || loading;
let currentItem;
let hasChanges = false;

View file

@ -1,78 +1,74 @@
define(['css!./loading'], function () {
'use strict';
import 'css!./loading';
var loadingElem;
var layer1;
var layer2;
var layer3;
var layer4;
var circleLefts;
var circleRights;
let loadingElem;
let layer1;
let layer2;
let layer3;
let layer4;
let circleLefts;
let circleRights;
return {
show: function () {
var elem = loadingElem;
export function show() {
let elem = loadingElem;
if (!elem) {
elem = document.createElement('div');
loadingElem = elem;
if (!elem) {
elem = document.createElement('div');
loadingElem = elem;
elem.classList.add('docspinner');
elem.classList.add('mdl-spinner');
elem.classList.add('docspinner');
elem.classList.add('mdl-spinner');
elem.innerHTML = '<div class="mdl-spinner__layer mdl-spinner__layer-1"><div class="mdl-spinner__circle-clipper mdl-spinner__left"><div class="mdl-spinner__circle mdl-spinner__circleLeft"></div></div><div class="mdl-spinner__circle-clipper mdl-spinner__right"><div class="mdl-spinner__circle mdl-spinner__circleRight"></div></div></div><div class="mdl-spinner__layer mdl-spinner__layer-2"><div class="mdl-spinner__circle-clipper mdl-spinner__left"><div class="mdl-spinner__circle mdl-spinner__circleLeft"></div></div><div class="mdl-spinner__circle-clipper mdl-spinner__right"><div class="mdl-spinner__circle mdl-spinner__circleRight"></div></div></div><div class="mdl-spinner__layer mdl-spinner__layer-3"><div class="mdl-spinner__circle-clipper mdl-spinner__left"><div class="mdl-spinner__circle mdl-spinner__circleLeft"></div></div><div class="mdl-spinner__circle-clipper mdl-spinner__right"><div class="mdl-spinner__circle mdl-spinner__circleRight"></div></div></div><div class="mdl-spinner__layer mdl-spinner__layer-4"><div class="mdl-spinner__circle-clipper mdl-spinner__left"><div class="mdl-spinner__circle mdl-spinner__circleLeft"></div></div><div class="mdl-spinner__circle-clipper mdl-spinner__right"><div class="mdl-spinner__circle mdl-spinner__circleRight"></div></div></div>';
elem.innerHTML = '<div class="mdl-spinner__layer mdl-spinner__layer-1"><div class="mdl-spinner__circle-clipper mdl-spinner__left"><div class="mdl-spinner__circle mdl-spinner__circleLeft"></div></div><div class="mdl-spinner__circle-clipper mdl-spinner__right"><div class="mdl-spinner__circle mdl-spinner__circleRight"></div></div></div><div class="mdl-spinner__layer mdl-spinner__layer-2"><div class="mdl-spinner__circle-clipper mdl-spinner__left"><div class="mdl-spinner__circle mdl-spinner__circleLeft"></div></div><div class="mdl-spinner__circle-clipper mdl-spinner__right"><div class="mdl-spinner__circle mdl-spinner__circleRight"></div></div></div><div class="mdl-spinner__layer mdl-spinner__layer-3"><div class="mdl-spinner__circle-clipper mdl-spinner__left"><div class="mdl-spinner__circle mdl-spinner__circleLeft"></div></div><div class="mdl-spinner__circle-clipper mdl-spinner__right"><div class="mdl-spinner__circle mdl-spinner__circleRight"></div></div></div><div class="mdl-spinner__layer mdl-spinner__layer-4"><div class="mdl-spinner__circle-clipper mdl-spinner__left"><div class="mdl-spinner__circle mdl-spinner__circleLeft"></div></div><div class="mdl-spinner__circle-clipper mdl-spinner__right"><div class="mdl-spinner__circle mdl-spinner__circleRight"></div></div></div>';
document.body.appendChild(elem);
document.body.appendChild(elem);
layer1 = elem.querySelector('.mdl-spinner__layer-1');
layer2 = elem.querySelector('.mdl-spinner__layer-2');
layer3 = elem.querySelector('.mdl-spinner__layer-3');
layer4 = elem.querySelector('.mdl-spinner__layer-4');
layer1 = elem.querySelector('.mdl-spinner__layer-1');
layer2 = elem.querySelector('.mdl-spinner__layer-2');
layer3 = elem.querySelector('.mdl-spinner__layer-3');
layer4 = elem.querySelector('.mdl-spinner__layer-4');
circleLefts = elem.querySelectorAll('.mdl-spinner__circleLeft');
circleRights = elem.querySelectorAll('.mdl-spinner__circleRight');
}
circleLefts = elem.querySelectorAll('.mdl-spinner__circleLeft');
circleRights = elem.querySelectorAll('.mdl-spinner__circleRight');
}
elem.classList.add('mdlSpinnerActive');
elem.classList.add('mdlSpinnerActive');
layer1.classList.add('mdl-spinner__layer-1-active');
layer2.classList.add('mdl-spinner__layer-2-active');
layer3.classList.add('mdl-spinner__layer-3-active');
layer4.classList.add('mdl-spinner__layer-4-active');
layer1.classList.add('mdl-spinner__layer-1-active');
layer2.classList.add('mdl-spinner__layer-2-active');
layer3.classList.add('mdl-spinner__layer-3-active');
layer4.classList.add('mdl-spinner__layer-4-active');
var i;
var length;
for (let i = 0, length = circleLefts.length; i < length; i++) {
circleLefts[i].classList.add('mdl-spinner__circleLeft-active');
}
for (i = 0, length = circleLefts.length; i < length; i++) {
circleLefts[i].classList.add('mdl-spinner__circleLeft-active');
}
for (let i = 0, length = circleRights.length; i < length; i++) {
circleRights[i].classList.add('mdl-spinner__circleRight-active');
}
}
for (i = 0, length = circleRights.length; i < length; i++) {
circleRights[i].classList.add('mdl-spinner__circleRight-active');
}
},
hide: function () {
var elem = loadingElem;
export function hide() {
const elem = loadingElem;
if (elem) {
elem.classList.remove('mdlSpinnerActive');
if (elem) {
elem.classList.remove('mdlSpinnerActive');
elem.classList.remove('mdl-spinner__layer-1-active');
elem.classList.remove('mdl-spinner__layer-2-active');
elem.classList.remove('mdl-spinner__layer-3-active');
elem.classList.remove('mdl-spinner__layer-4-active');
elem.classList.remove('mdl-spinner__layer-1-active');
elem.classList.remove('mdl-spinner__layer-2-active');
elem.classList.remove('mdl-spinner__layer-3-active');
elem.classList.remove('mdl-spinner__layer-4-active');
var i;
var length;
for (i = 0, length = circleLefts.length; i < length; i++) {
circleLefts[i].classList.remove('mdl-spinner__circleLeft-active');
}
for (i = 0, length = circleRights.length; i < length; i++) {
circleRights[i].classList.remove('mdl-spinner__circleRight-active');
}
}
for (let i = 0, length = circleLefts.length; i < length; i++) {
circleLefts[i].classList.remove('mdl-spinner__circleLeft-active');
}
};
});
for (let i = 0, length = circleRights.length; i < length; i++) {
circleRights[i].classList.remove('mdl-spinner__circleRight-active');
}
}
}
export default {
show: show,
hide: hide
};

View file

@ -1,6 +1,7 @@
define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'playQueueManager', 'userSettings', 'globalize', 'connectionManager', 'loading', 'apphost', 'screenfull'], function (events, datetime, appSettings, itemHelper, pluginManager, PlayQueueManager, userSettings, globalize, connectionManager, loading, apphost, screenfull) {
'use strict';
loading = loading.default || loading;
PlayQueueManager = PlayQueueManager.default || PlayQueueManager;
function enableLocalPlaylistManagement(player) {

View file

@ -1,6 +1,8 @@
define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'imageLoader', 'scrollStyles', 'emby-button', 'emby-collapse', 'emby-input', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'material-icons', 'flexStyles'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper, imageLoader) {
'use strict';
loading = loading.default || loading;
var currentDialog;
var recordingDeleted = false;
var currentItemId;

View file

@ -1,6 +1,8 @@
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';
loading = loading.default || loading;
function loadData(parent, program, apiClient) {
if (program.IsSeries) {
parent.querySelector('.recordSeriesContainer').classList.remove('hide');

View file

@ -1,6 +1,8 @@
define(['globalize', 'loading', 'connectionManager'], function (globalize, loading, connectionManager) {
'use strict';
loading = loading.default || loading;
function changeRecordingToSeries(apiClient, timerId, programId, confirmTimerCancellation) {
loading.show();

View file

@ -1,6 +1,8 @@
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';
loading = loading.default || loading;
var currentDialog;
var recordingUpdated = false;
var recordingDeleted = false;

View file

@ -119,9 +119,9 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
var nowPlayingServerId = (item.ServerId || serverId);
if (item.Type == 'Audio' || item.MediaStreams[0].Type == 'Audio') {
var songName = item.Name;
if (item.Album != null && item.Artists != null) {
var artistsSeries = '';
var albumName = item.Album;
var artistsSeries = '';
var albumName = '';
if (item.Artists != null) {
if (item.ArtistItems != null) {
for (const artist of item.ArtistItems) {
let artistName = artist.Name;
@ -142,9 +142,12 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL
}
}
}
context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries;
context.querySelector('.nowPlayingAlbum').innerHTML = '<a class="button-link emby-button" is="emby-linkbutton" href="details?id=' + item.AlbumId + `&serverId=${nowPlayingServerId}">${albumName}</a>`;
}
if (item.Album != null) {
albumName = '<a class="button-link emby-button" is="emby-linkbutton" href="details?id=' + item.AlbumId + `&serverId=${nowPlayingServerId}">` + item.Album + '</a>';
}
context.querySelector('.nowPlayingAlbum').innerHTML = albumName;
context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries;
context.querySelector('.nowPlayingSongName').innerHTML = songName;
} else if (item.Type == 'Episode') {
if (item.SeasonName != null) {

View file

@ -1,6 +1,8 @@
define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings', 'connectionManager', 'loading', 'focusManager', 'dom', 'apphost', 'emby-select', 'listViewStyle', 'paper-icon-button-light', 'css!./../formdialog', 'material-icons', 'css!./subtitleeditor', 'emby-button', 'flexStyles'], function (dialogHelper, require, layoutManager, globalize, userSettings, connectionManager, loading, focusManager, dom, appHost) {
'use strict';
loading = loading.default || loading;
var currentItem;
var hasChanges;

View file

@ -1,6 +1,8 @@
define(['dialogHelper', 'dom', 'layoutManager', 'connectionManager', 'globalize', 'loading', 'browser', 'focusManager', 'scrollHelper', 'material-icons', 'formDialogStyle', 'emby-button', 'emby-itemscontainer', 'cardStyle'], function (dialogHelper, dom, layoutManager, connectionManager, globalize, loading, browser, focusManager, scrollHelper) {
'use strict';
loading = loading.default || loading;
var enableFocusTransform = !browser.slow && !browser.edge;
function getEditorHtml() {

View file

@ -1,6 +1,8 @@
define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'listViewStyle', 'emby-input', 'emby-select', 'emby-button', 'flexStyles'], function ($, loading, globalize) {
'use strict';
loading = loading.default || loading;
return function (page, providerId, options) {
function reload() {
loading.show();

View file

@ -1,6 +1,8 @@
define(['jQuery', 'loading', 'globalize', 'emby-checkbox', 'emby-input', 'listViewStyle', 'paper-icon-button-light'], function ($, loading, globalize) {
'use strict';
loading = loading.default || loading;
return function (page, providerId, options) {
function getListingProvider(config, id) {
if (config && id) {

View file

@ -1,6 +1,8 @@
define(['loading', 'libraryMenu', 'globalize', 'listViewStyle', 'emby-button'], function(loading, libraryMenu, globalize) {
'use strict';
loading = loading.default || loading;
function reload(page) {
loading.show();
ApiClient.getJSON(ApiClient.getUrl('Notifications/Types')).then(function(list) {

View file

@ -1,6 +1,8 @@
define(['jQuery', 'loading', 'libraryMenu', 'globalize', 'connectionManager', 'emby-button'], function ($, loading, libraryMenu, globalize, connectionManager) {
'use strict';
loading = loading.default || loading;
function populateHistory(packageInfo, page) {
var html = '';
var length = Math.min(packageInfo.versions.length, 10);

View file

@ -1,6 +1,8 @@
define(['loading', 'libraryMenu', 'globalize', 'cardStyle', 'emby-button', 'emby-checkbox', 'emby-select'], function (loading, libraryMenu, globalize) {
'use strict';
loading = loading.default || loading;
function reloadList(page) {
loading.show();
var promise1 = ApiClient.getAvailablePlugins();

View file

@ -1,6 +1,8 @@
define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'], function (loading, libraryMenu, dom, globalize) {
'use strict';
loading = loading.default || loading;
function deletePlugin(page, uniqueid, name) {
var msg = globalize.translate('UninstallPluginConfirmation', name);

View file

@ -1,6 +1,8 @@
define(['loading', 'scripts/editorsidebar'], function (loading) {
'use strict';
loading = loading.default || loading;
function reload(context, itemId) {
loading.show();

View file

@ -1,6 +1,8 @@
define(['userSettings', 'loading', 'connectionManager', 'apphost', 'layoutManager', 'focusManager', 'homeSections', 'emby-itemscontainer'], function (userSettings, loading, connectionManager, appHost, layoutManager, focusManager, homeSections) {
'use strict';
loading = loading.default || loading;
function HomeTab(view, params) {
this.view = view;
this.params = params;

View file

@ -29,6 +29,8 @@ import 'emby-select';
/* eslint-disable indent */
loading = loading.default || loading;
function getPromise(apiClient, params) {
const id = params.id;

View file

@ -1,6 +1,8 @@
define(['globalize', 'listView', 'layoutManager', 'userSettings', 'focusManager', 'cardBuilder', 'loading', 'connectionManager', 'alphaNumericShortcuts', 'scroller', 'playbackManager', 'alphaPicker', 'emby-itemscontainer', 'emby-scroller'], function (globalize, listView, layoutManager, userSettings, focusManager, cardBuilder, loading, connectionManager, AlphaNumericShortcuts, scroller, playbackManager, AlphaPicker) {
'use strict';
loading = loading.default || loading;
function getInitialLiveTvQuery(instance, params) {
var query = {
UserId: connectionManager.getApiClient(params.serverId).getCurrentUserId(),

View file

@ -1,6 +1,7 @@
define(['cardBuilder', 'imageLoader', 'libraryBrowser', 'loading', 'events', 'userSettings', 'emby-itemscontainer'], function (cardBuilder, imageLoader, libraryBrowser, loading, events, userSettings) {
'use strict';
loading = loading.default || loading;
libraryBrowser = libraryBrowser.default || libraryBrowser;
return function (view, params, tabContent) {

View file

@ -1,6 +1,8 @@
define(['layoutManager', 'loading', 'cardBuilder', 'apphost', 'imageLoader', 'scripts/livetvcomponents', 'listViewStyle', 'emby-itemscontainer'], function (layoutManager, loading, cardBuilder, appHost, imageLoader) {
'use strict';
loading = loading.default || loading;
function renderRecordings(elem, recordings, cardOptions, scrollX) {
if (!elem) {
return;

View file

@ -1,6 +1,8 @@
define(['layoutManager', 'cardBuilder', 'apphost', 'imageLoader', 'loading', 'scripts/livetvcomponents', 'emby-button', 'emby-itemscontainer'], function (layoutManager, cardBuilder, appHost, imageLoader, loading) {
'use strict';
loading = loading.default || loading;
function enableScrollX() {
return !layoutManager.desktop;
}

View file

@ -1,6 +1,8 @@
define(['datetime', 'cardBuilder', 'imageLoader', 'apphost', 'loading', 'paper-icon-button-light', 'emby-button'], function (datetime, cardBuilder, imageLoader, appHost, loading) {
'use strict';
loading = loading.default || loading;
function renderTimers(context, timers) {
var html = '';
html += cardBuilder.getCardsHtml({

View file

@ -1,6 +1,8 @@
define(['layoutManager', 'userSettings', 'inputManager', 'loading', 'globalize', 'libraryBrowser', 'mainTabsManager', 'cardBuilder', 'apphost', 'imageLoader', 'scrollStyles', 'emby-itemscontainer', 'emby-tabs', 'emby-button'], function (layoutManager, userSettings, inputManager, loading, globalize, libraryBrowser, mainTabsManager, cardBuilder, appHost, imageLoader) {
'use strict';
loading = loading.default || loading;
function enableScrollX() {
return !layoutManager.desktop;
}

View file

@ -1,6 +1,8 @@
define(['events', 'loading', 'globalize'], function (events, loading, globalize) {
'use strict';
loading = loading.default || loading;
function onListingsSubmitted() {
Dashboard.navigate('livetvstatus.html');
}

View file

@ -1,65 +1,70 @@
define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading, globalize) {
'use strict';
import $ from 'jQuery';
import loading from 'loading';
import globalize from 'globalize';
import 'emby-button';
function loadPage(page, config) {
$('.liveTvSettingsForm', page).show();
$('.noLiveTvServices', page).hide();
$('#selectGuideDays', page).val(config.GuideDays || '');
$('#txtPrePaddingMinutes', page).val(config.PrePaddingSeconds / 60);
$('#txtPostPaddingMinutes', page).val(config.PostPaddingSeconds / 60);
page.querySelector('#txtRecordingPath').value = config.RecordingPath || '';
page.querySelector('#txtMovieRecordingPath').value = config.MovieRecordingPath || '';
page.querySelector('#txtSeriesRecordingPath').value = config.SeriesRecordingPath || '';
page.querySelector('#txtPostProcessor').value = config.RecordingPostProcessor || '';
page.querySelector('#txtPostProcessorArguments').value = config.RecordingPostProcessorArguments || '';
loading.hide();
}
loading = loading.default || loading;
function onSubmit() {
loading.show();
var form = this;
ApiClient.getNamedConfiguration('livetv').then(function (config) {
config.GuideDays = $('#selectGuideDays', form).val() || null;
var recordingPath = form.querySelector('#txtRecordingPath').value || null;
var movieRecordingPath = form.querySelector('#txtMovieRecordingPath').value || null;
var seriesRecordingPath = form.querySelector('#txtSeriesRecordingPath').value || null;
var recordingPathChanged = recordingPath != config.RecordingPath || movieRecordingPath != config.MovieRecordingPath || seriesRecordingPath != config.SeriesRecordingPath;
config.RecordingPath = recordingPath;
config.MovieRecordingPath = movieRecordingPath;
config.SeriesRecordingPath = seriesRecordingPath;
config.RecordingEncodingFormat = 'mkv';
config.PrePaddingSeconds = 60 * $('#txtPrePaddingMinutes', form).val();
config.PostPaddingSeconds = 60 * $('#txtPostPaddingMinutes', form).val();
config.RecordingPostProcessor = $('#txtPostProcessor', form).val();
config.RecordingPostProcessorArguments = $('#txtPostProcessorArguments', form).val();
ApiClient.updateNamedConfiguration('livetv', config).then(function () {
Dashboard.processServerConfigurationUpdateResult();
showSaveMessage(recordingPathChanged);
});
function loadPage(page, config) {
$('.liveTvSettingsForm', page).show();
$('.noLiveTvServices', page).hide();
$('#selectGuideDays', page).val(config.GuideDays || '');
$('#txtPrePaddingMinutes', page).val(config.PrePaddingSeconds / 60);
$('#txtPostPaddingMinutes', page).val(config.PostPaddingSeconds / 60);
page.querySelector('#txtRecordingPath').value = config.RecordingPath || '';
page.querySelector('#txtMovieRecordingPath').value = config.MovieRecordingPath || '';
page.querySelector('#txtSeriesRecordingPath').value = config.SeriesRecordingPath || '';
page.querySelector('#txtPostProcessor').value = config.RecordingPostProcessor || '';
page.querySelector('#txtPostProcessorArguments').value = config.RecordingPostProcessorArguments || '';
loading.hide();
}
function onSubmit() {
loading.show();
const form = this;
ApiClient.getNamedConfiguration('livetv').then(function (config) {
config.GuideDays = $('#selectGuideDays', form).val() || null;
const recordingPath = form.querySelector('#txtRecordingPath').value || null;
const movieRecordingPath = form.querySelector('#txtMovieRecordingPath').value || null;
const seriesRecordingPath = form.querySelector('#txtSeriesRecordingPath').value || null;
const recordingPathChanged = recordingPath != config.RecordingPath || movieRecordingPath != config.MovieRecordingPath || seriesRecordingPath != config.SeriesRecordingPath;
config.RecordingPath = recordingPath;
config.MovieRecordingPath = movieRecordingPath;
config.SeriesRecordingPath = seriesRecordingPath;
config.RecordingEncodingFormat = 'mkv';
config.PrePaddingSeconds = 60 * $('#txtPrePaddingMinutes', form).val();
config.PostPaddingSeconds = 60 * $('#txtPostPaddingMinutes', form).val();
config.RecordingPostProcessor = $('#txtPostProcessor', form).val();
config.RecordingPostProcessorArguments = $('#txtPostProcessorArguments', form).val();
ApiClient.updateNamedConfiguration('livetv', config).then(function () {
Dashboard.processServerConfigurationUpdateResult();
showSaveMessage(recordingPathChanged);
});
return false;
});
return false;
}
function showSaveMessage(recordingPathChanged) {
let msg = '';
if (recordingPathChanged) {
msg += globalize.translate('MessageChangeRecordingPath');
}
function showSaveMessage(recordingPathChanged) {
var msg = '';
if (recordingPathChanged) {
msg += globalize.translate('MessageChangeRecordingPath');
}
if (msg) {
require(['alert'], function (alert) {
alert(msg);
});
}
if (msg) {
import('alert').then(({default: alert}) => {
alert(msg);
});
}
}
export default function () {
$(document).on('pageinit', '#liveTvSettingsPage', function () {
var page = this;
const page = this;
$('.liveTvSettingsForm').off('submit', onSubmit).on('submit', onSubmit);
$('#btnSelectRecordingPath', page).on('click.selectDirectory', function () {
require(['directorybrowser'], function (directoryBrowser) {
var picker = new directoryBrowser.default();
import('directorybrowser').then(({default: directoryBrowser}) => {
const picker = new directoryBrowser();
picker.show({
callback: function (path) {
if (path) {
@ -73,8 +78,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading,
});
});
$('#btnSelectMovieRecordingPath', page).on('click.selectDirectory', function () {
require(['directorybrowser'], function (directoryBrowser) {
var picker = new directoryBrowser.default();
import('directorybrowser').then(({default: directoryBrowser}) => {
const picker = new directoryBrowser();
picker.show({
callback: function (path) {
if (path) {
@ -88,8 +93,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading,
});
});
$('#btnSelectSeriesRecordingPath', page).on('click.selectDirectory', function () {
require(['directorybrowser'], function (directoryBrowser) {
var picker = new directoryBrowser.default();
import('directorybrowser').then(({default: directoryBrowser}) => {
const picker = new directoryBrowser();
picker.show({
callback: function (path) {
if (path) {
@ -103,8 +108,8 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading,
});
});
$('#btnSelectPostProcessorPath', page).on('click.selectDirectory', function () {
require(['directorybrowser'], function (directoryBrowser) {
var picker = new directoryBrowser.default();
import('directorybrowser').then(({default: directoryBrowser}) => {
const picker = new directoryBrowser();
picker.show({
includeFiles: true,
callback: function (path) {
@ -119,9 +124,9 @@ define(['jQuery', 'loading', 'globalize', 'emby-button'], function ($, loading,
});
}).on('pageshow', '#liveTvSettingsPage', function () {
loading.show();
var page = this;
const page = this;
ApiClient.getNamedConfiguration('livetv').then(function (config) {
loadPage(page, config);
});
});
});
}

View file

@ -1,294 +1,305 @@
define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layoutManager', 'loading', 'browser', 'listViewStyle', 'flexStyles', 'emby-itemscontainer', 'cardStyle', 'material-icons', 'emby-button'], function ($, globalize, taskButton, dom, libraryMenu, layoutManager, loading, browser) {
'use strict';
import $ from 'jQuery';
import globalize from 'globalize';
import taskButton from 'scripts/taskbutton';
import dom from 'dom';
import layoutManager from 'layoutManager';
import loading from 'loading';
import browser from 'browser';
import 'listViewStyle';
import 'flexStyles';
import 'emby-itemscontainer';
import 'cardStyle';
import 'material-icons';
import 'emby-button';
var enableFocusTransform = !browser.slow && !browser.edge;
const enableFocusTransform = !browser.slow && !browser.edge;
function getDeviceHtml(device) {
var padderClass;
var html = '';
var cssClass = 'card scalableCard';
var cardBoxCssClass = 'cardBox visualCardBox';
cssClass += ' backdropCard backdropCard-scalable';
padderClass = 'cardPadder-backdrop';
function getDeviceHtml(device) {
let padderClass;
let html = '';
let cssClass = 'card scalableCard';
let cardBoxCssClass = 'cardBox visualCardBox';
cssClass += ' backdropCard backdropCard-scalable';
padderClass = 'cardPadder-backdrop';
// TODO move card creation code to Card component
// TODO move card creation code to Card component
if (layoutManager.tv) {
cssClass += ' show-focus';
if (layoutManager.tv) {
cssClass += ' show-focus';
if (enableFocusTransform) {
cssClass += ' show-animation';
}
if (enableFocusTransform) {
cssClass += ' show-animation';
}
html += '<div type="button" class="' + cssClass + '" data-id="' + device.Id + '">';
html += '<div class="' + cardBoxCssClass + '">';
html += '<div class="cardScalable visualCardBox-cardScalable">';
html += '<div class="' + padderClass + '"></div>';
html += '<div class="cardContent searchImage">';
html += '<div class="cardImageContainer coveredImage"><span class="cardImageIcon material-icons dvr"></span></div>';
html += '</div>';
html += '</div>';
html += '<div class="cardFooter visualCardBox-cardFooter">';
html += '<button is="paper-icon-button-light" class="itemAction btnCardOptions autoSize" data-action="menu"><span class="material-icons more_vert"></span></button>';
html += '<div class="cardText">' + (device.FriendlyName || getTunerName(device.Type)) + '</div>';
html += '<div class="cardText cardText-secondary">';
html += device.Url || '&nbsp;';
html += '</div>';
html += '</div>';
html += '</div>';
return html += '</div>';
}
function renderDevices(page, devices) {
var html = devices.map(getDeviceHtml).join('');
page.querySelector('.devicesList').innerHTML = html;
}
html += '<div type="button" class="' + cssClass + '" data-id="' + device.Id + '">';
html += '<div class="' + cardBoxCssClass + '">';
html += '<div class="cardScalable visualCardBox-cardScalable">';
html += '<div class="' + padderClass + '"></div>';
html += '<div class="cardContent searchImage">';
html += '<div class="cardImageContainer coveredImage"><span class="cardImageIcon material-icons dvr"></span></div>';
html += '</div>';
html += '</div>';
html += '<div class="cardFooter visualCardBox-cardFooter">';
html += '<button is="paper-icon-button-light" class="itemAction btnCardOptions autoSize" data-action="menu"><span class="material-icons more_vert"></span></button>';
html += '<div class="cardText">' + (device.FriendlyName || getTunerName(device.Type)) + '</div>';
html += '<div class="cardText cardText-secondary">';
html += device.Url || '&nbsp;';
html += '</div>';
html += '</div>';
html += '</div>';
return html += '</div>';
}
function deleteDevice(page, id) {
var message = globalize.translate('MessageConfirmDeleteTunerDevice');
function renderDevices(page, devices) {
page.querySelector('.devicesList').innerHTML = devices.map(getDeviceHtml).join('');
}
require(['confirm'], function (confirm) {
confirm.default(message, globalize.translate('HeaderDeleteDevice')).then(function () {
loading.show();
ApiClient.ajax({
type: 'DELETE',
url: ApiClient.getUrl('LiveTv/TunerHosts', {
Id: id
})
}).then(function () {
reload(page);
});
function deleteDevice(page, id) {
const message = globalize.translate('MessageConfirmDeleteTunerDevice');
import('confirm').then(({default: confirm}) => {
confirm(message, globalize.translate('HeaderDeleteDevice')).then(function () {
loading.show();
ApiClient.ajax({
type: 'DELETE',
url: ApiClient.getUrl('LiveTv/TunerHosts', {
Id: id
})
}).then(function () {
reload(page);
});
});
}
});
}
function reload(page) {
loading.show();
ApiClient.getNamedConfiguration('livetv').then(function (config) {
renderDevices(page, config.TunerHosts);
renderProviders(page, config.ListingProviders);
function reload(page) {
loading.show();
ApiClient.getNamedConfiguration('livetv').then(function (config) {
renderDevices(page, config.TunerHosts);
renderProviders(page, config.ListingProviders);
});
loading.hide();
}
function submitAddDeviceForm(page) {
page.querySelector('.dlgAddDevice').close();
loading.show();
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('LiveTv/TunerHosts'),
data: JSON.stringify({
Type: $('#selectTunerDeviceType', page).val(),
Url: $('#txtDevicePath', page).val()
}),
contentType: 'application/json'
}).then(function () {
reload(page);
}, function () {
Dashboard.alert({
message: globalize.translate('ErrorAddingTunerDevice')
});
loading.hide();
}
});
}
function submitAddDeviceForm(page) {
page.querySelector('.dlgAddDevice').close();
loading.show();
ApiClient.ajax({
type: 'POST',
url: ApiClient.getUrl('LiveTv/TunerHosts'),
data: JSON.stringify({
Type: $('#selectTunerDeviceType', page).val(),
Url: $('#txtDevicePath', page).val()
}),
contentType: 'application/json'
}).then(function () {
reload(page);
}, function () {
Dashboard.alert({
message: globalize.translate('ErrorAddingTunerDevice')
});
});
}
function renderProviders(page, providers) {
let html = '';
function renderProviders(page, providers) {
var html = '';
if (providers.length) {
html += '<div class="paperList">';
for (var i = 0, length = providers.length; i < length; i++) {
var provider = providers[i];
html += '<div class="listItem">';
html += '<span class="listItemIcon material-icons dvr"></span>';
html += '<div class="listItemBody two-line">';
html += '<a is="emby-linkbutton" style="display:block;padding:0;margin:0;text-align:left;" class="clearLink" href="' + getProviderConfigurationUrl(provider.Type) + '&id=' + provider.Id + '">';
html += '<h3 class="listItemBodyText">';
html += getProviderName(provider.Type);
html += '</h3>';
html += '<div class="listItemBodyText secondary">';
html += provider.Path || provider.ListingsId || '';
html += '</div>';
html += '</a>';
html += '</div>';
html += '<button type="button" is="paper-icon-button-light" class="btnOptions" data-id="' + provider.Id + '"><span class="material-icons listItemAside more_vert"></span></button>';
html += '</div>';
}
if (providers.length) {
html += '<div class="paperList">';
for (let i = 0, length = providers.length; i < length; i++) {
const provider = providers[i];
html += '<div class="listItem">';
html += '<span class="listItemIcon material-icons dvr"></span>';
html += '<div class="listItemBody two-line">';
html += '<a is="emby-linkbutton" style="display:block;padding:0;margin:0;text-align:left;" class="clearLink" href="' + getProviderConfigurationUrl(provider.Type) + '&id=' + provider.Id + '">';
html += '<h3 class="listItemBodyText">';
html += getProviderName(provider.Type);
html += '</h3>';
html += '<div class="listItemBodyText secondary">';
html += provider.Path || provider.ListingsId || '';
html += '</div>';
html += '</a>';
html += '</div>';
html += '<button type="button" is="paper-icon-button-light" class="btnOptions" data-id="' + provider.Id + '"><span class="material-icons listItemAside more_vert"></span></button>';
html += '</div>';
}
var elem = $('.providerList', page).html(html);
$('.btnOptions', elem).on('click', function () {
var id = this.getAttribute('data-id');
showProviderOptions(page, id, this);
});
html += '</div>';
}
function showProviderOptions(page, providerId, button) {
var items = [];
items.push({
name: globalize.translate('ButtonDelete'),
id: 'delete'
});
items.push({
name: globalize.translate('MapChannels'),
id: 'map'
});
const elem = $('.providerList', page).html(html);
$('.btnOptions', elem).on('click', function () {
const id = this.getAttribute('data-id');
showProviderOptions(page, id, this);
});
}
require(['actionsheet'], function (actionsheet) {
actionsheet.show({
items: items,
positionTo: button
}).then(function (id) {
switch (id) {
case 'delete':
deleteProvider(page, providerId);
break;
function showProviderOptions(page, providerId, button) {
const items = [];
items.push({
name: globalize.translate('ButtonDelete'),
id: 'delete'
});
items.push({
name: globalize.translate('MapChannels'),
id: 'map'
});
case 'map':
mapChannels(page, providerId);
}
});
});
}
import('actionsheet').then(({default: actionsheet}) => {
actionsheet.show({
items: items,
positionTo: button
}).then(function (id) {
switch (id) {
case 'delete':
deleteProvider(page, providerId);
break;
function mapChannels(page, providerId) {
require(['components/channelMapper/channelMapper'], function (channelMapper) {
new channelMapper.default({
serverId: ApiClient.serverInfo().Id,
providerId: providerId
}).show();
});
}
function deleteProvider(page, id) {
var message = globalize.translate('MessageConfirmDeleteGuideProvider');
require(['confirm'], function (confirm) {
confirm.default(message, globalize.translate('HeaderDeleteProvider')).then(function () {
loading.show();
ApiClient.ajax({
type: 'DELETE',
url: ApiClient.getUrl('LiveTv/ListingProviders', {
Id: id
})
}).then(function () {
reload(page);
}, function () {
reload(page);
});
});
});
}
function getTunerName(providerId) {
switch (providerId = providerId.toLowerCase()) {
case 'm3u':
return 'M3U';
case 'hdhomerun':
return 'HDHomeRun';
case 'hauppauge':
return 'Hauppauge';
case 'satip':
return 'DVB';
default:
return 'Unknown';
}
}
function getProviderName(providerId) {
switch (providerId = providerId.toLowerCase()) {
case 'schedulesdirect':
return 'Schedules Direct';
case 'xmltv':
return 'XMLTV';
default:
return 'Unknown';
}
}
function getProviderConfigurationUrl(providerId) {
switch (providerId = providerId.toLowerCase()) {
case 'xmltv':
return 'livetvguideprovider.html?type=xmltv';
case 'schedulesdirect':
return 'livetvguideprovider.html?type=schedulesdirect';
}
}
function addProvider(button) {
var menuItems = [];
menuItems.push({
name: 'Schedules Direct',
id: 'SchedulesDirect'
});
menuItems.push({
name: 'XMLTV',
id: 'xmltv'
});
require(['actionsheet'], function (actionsheet) {
actionsheet.show({
items: menuItems,
positionTo: button,
callback: function (id) {
Dashboard.navigate(getProviderConfigurationUrl(id));
}
});
});
}
function addDevice(button) {
Dashboard.navigate('livetvtuner.html');
}
function showDeviceMenu(button, tunerDeviceId) {
var items = [];
items.push({
name: globalize.translate('ButtonDelete'),
id: 'delete'
});
items.push({
name: globalize.translate('ButtonEdit'),
id: 'edit'
});
require(['actionsheet'], function (actionsheet) {
actionsheet.show({
items: items,
positionTo: button
}).then(function (id) {
switch (id) {
case 'delete':
deleteDevice(dom.parentWithClass(button, 'page'), tunerDeviceId);
break;
case 'edit':
Dashboard.navigate('livetvtuner.html?id=' + tunerDeviceId);
}
});
});
}
function onDevicesListClick(e) {
var card = dom.parentWithClass(e.target, 'card');
if (card) {
var id = card.getAttribute('data-id');
var btnCardOptions = dom.parentWithClass(e.target, 'btnCardOptions');
if (btnCardOptions) {
showDeviceMenu(btnCardOptions, id);
} else {
Dashboard.navigate('livetvtuner.html?id=' + id);
case 'map':
mapChannels(page, providerId);
}
});
});
}
function mapChannels(page, providerId) {
import('components/channelMapper/channelMapper').then(({default: channelMapper}) => {
new channelMapper({
serverId: ApiClient.serverInfo().Id,
providerId: providerId
}).show();
});
}
function deleteProvider(page, id) {
const message = globalize.translate('MessageConfirmDeleteGuideProvider');
import('confirm').then(({default: confirm}) => {
confirm(message, globalize.translate('HeaderDeleteProvider')).then(function () {
loading.show();
ApiClient.ajax({
type: 'DELETE',
url: ApiClient.getUrl('LiveTv/ListingProviders', {
Id: id
})
}).then(function () {
reload(page);
}, function () {
reload(page);
});
});
});
}
function getTunerName(providerId) {
switch (providerId = providerId.toLowerCase()) {
case 'm3u':
return 'M3U';
case 'hdhomerun':
return 'HDHomeRun';
case 'hauppauge':
return 'Hauppauge';
case 'satip':
return 'DVB';
default:
return 'Unknown';
}
}
function getProviderName(providerId) {
switch (providerId = providerId.toLowerCase()) {
case 'schedulesdirect':
return 'Schedules Direct';
case 'xmltv':
return 'XMLTV';
default:
return 'Unknown';
}
}
function getProviderConfigurationUrl(providerId) {
switch (providerId = providerId.toLowerCase()) {
case 'xmltv':
return 'livetvguideprovider.html?type=xmltv';
case 'schedulesdirect':
return 'livetvguideprovider.html?type=schedulesdirect';
}
}
function addProvider(button) {
const menuItems = [];
menuItems.push({
name: 'Schedules Direct',
id: 'SchedulesDirect'
});
menuItems.push({
name: 'XMLTV',
id: 'xmltv'
});
import('actionsheet').then(({default: actionsheet}) => {
actionsheet.show({
items: menuItems,
positionTo: button,
callback: function (id) {
Dashboard.navigate(getProviderConfigurationUrl(id));
}
});
});
}
function addDevice(button) {
Dashboard.navigate('livetvtuner.html');
}
function showDeviceMenu(button, tunerDeviceId) {
const items = [];
items.push({
name: globalize.translate('ButtonDelete'),
id: 'delete'
});
items.push({
name: globalize.translate('ButtonEdit'),
id: 'edit'
});
import('actionsheet').then(({default: actionsheet}) => {
actionsheet.show({
items: items,
positionTo: button
}).then(function (id) {
switch (id) {
case 'delete':
deleteDevice(dom.parentWithClass(button, 'page'), tunerDeviceId);
break;
case 'edit':
Dashboard.navigate('livetvtuner.html?id=' + tunerDeviceId);
}
});
});
}
function onDevicesListClick(e) {
const card = dom.parentWithClass(e.target, 'card');
if (card) {
const id = card.getAttribute('data-id');
const btnCardOptions = dom.parentWithClass(e.target, 'btnCardOptions');
if (btnCardOptions) {
showDeviceMenu(btnCardOptions, id);
} else {
Dashboard.navigate('livetvtuner.html?id=' + id);
}
}
}
export default function () {
$(document).on('pageinit', '#liveTvStatusPage', function () {
var page = this;
const page = this;
$('.btnAddDevice', page).on('click', function () {
addDevice(this);
});
@ -301,21 +312,21 @@ define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layo
});
page.querySelector('.devicesList').addEventListener('click', onDevicesListClick);
}).on('pageshow', '#liveTvStatusPage', function () {
var page = this;
const page = this;
reload(page);
taskButton.default({
taskButton({
mode: 'on',
progressElem: page.querySelector('.refreshGuideProgress'),
taskKey: 'RefreshGuide',
button: page.querySelector('.btnRefresh')
});
}).on('pagehide', '#liveTvStatusPage', function () {
var page = this;
taskButton.default({
const page = this;
taskButton({
mode: 'off',
progressElem: page.querySelector('.refreshGuideProgress'),
taskKey: 'RefreshGuide',
button: page.querySelector('.btnRefresh')
});
});
});
}

View file

@ -1,6 +1,7 @@
define(['loading', 'events', 'libraryBrowser', 'imageLoader', 'listView', 'cardBuilder', 'userSettings', 'globalize', 'emby-itemscontainer'], function (loading, events, libraryBrowser, imageLoader, listView, cardBuilder, userSettings, globalize) {
'use strict';
loading = loading.default || loading;
libraryBrowser = libraryBrowser.default || libraryBrowser;
return function (view, params, tabContent) {

View file

@ -1,6 +1,7 @@
define(['layoutManager', 'loading', 'libraryBrowser', 'cardBuilder', 'lazyLoader', 'apphost', 'globalize', 'appRouter', 'dom', 'emby-button'], function (layoutManager, loading, libraryBrowser, cardBuilder, lazyLoader, appHost, globalize, appRouter, dom) {
'use strict';
loading = loading.default || loading;
libraryBrowser = libraryBrowser.default || libraryBrowser;
return function (view, params, tabContent) {

View file

@ -1,6 +1,7 @@
define(['loading', 'layoutManager', 'userSettings', 'events', 'libraryBrowser', 'alphaPicker', 'listView', 'cardBuilder', 'globalize', 'emby-itemscontainer'], function (loading, layoutManager, userSettings, events, libraryBrowser, AlphaPicker, listView, cardBuilder, globalize) {
'use strict';
loading = loading.default || loading;
libraryBrowser = libraryBrowser.default || libraryBrowser;
return function (view, params, tabContent, options) {

View file

@ -1,6 +1,7 @@
define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'alphaPicker', 'listView', 'cardBuilder', 'userSettings', 'globalize', 'emby-itemscontainer'], function (layoutManager, loading, events, libraryBrowser, imageLoader, AlphaPicker, listView, cardBuilder, userSettings, globalize) {
'use strict';
loading = loading.default || loading;
libraryBrowser = libraryBrowser.default || libraryBrowser;
return function (view, params, tabContent) {

View file

@ -2,6 +2,7 @@ import connectionManager from 'connectionManager';
import loading from 'loading';
import keyboardnavigation from 'keyboardnavigation';
import dialogHelper from 'dialogHelper';
import dom from 'dom';
import events from 'events';
import 'css!./style';
import 'material-icons';
@ -93,23 +94,22 @@ export class BookPlayer {
onWindowKeyUp(e) {
let key = keyboardnavigation.getKeyName(e);
let rendition = this._rendition;
// TODO: depending on the event this can be the document or the rendition itself
let rendition = this._rendition || this;
let book = rendition.book;
if (this._loaded === false) return;
switch (key) {
case 'l':
case 'ArrowRight':
case 'Right':
if (this._loaded) {
book.package.metadata.direction === 'rtl' ? rendition.prev() : rendition.next();
}
book.package.metadata.direction === 'rtl' ? rendition.prev() : rendition.next();
break;
case 'j':
case 'ArrowLeft':
case 'Left':
if (this._loaded) {
book.package.metadata.direction === 'rtl' ? rendition.next() : rendition.prev();
}
book.package.metadata.direction === 'rtl' ? rendition.next() : rendition.prev();
break;
case 'Escape':
if (this._tocElement) {
@ -123,6 +123,25 @@ export class BookPlayer {
}
}
onTouchStart(e) {
// TODO: depending on the event this can be the document or the rendition itself
let rendition = this._rendition || this;
let book = rendition.book;
// check that the event is from the book or the document
if (!book || this._loaded === false) return;
// epubjs stores pages off the screen or something for preloading
// get the modulus of the touch event to account for the increased width
if (!e.touches || e.touches.length === 0) return;
let touch = e.touches[0].clientX % dom.getWindowSize().innerWidth;
if (touch < dom.getWindowSize().innerWidth / 2) {
book.package.metadata.direction === 'rtl' ? rendition.next() : rendition.prev();
} else {
book.package.metadata.direction === 'rtl' ? rendition.prev() : rendition.next();
}
}
onDialogClosed() {
this.stop();
}
@ -139,8 +158,11 @@ export class BookPlayer {
this.bindMediaElementEvents();
document.addEventListener('keyup', this.onWindowKeyUp);
document.addEventListener('touchstart', this.onTouchStart);
// FIXME: I don't really get why document keyup event is not triggered when epub is in focus
this._rendition.on('keyup', this.onWindowKeyUp);
this._rendition.on('touchstart', this.onTouchStart);
}
unbindMediaElementEvents() {
@ -155,9 +177,13 @@ export class BookPlayer {
if (this._mediaElement) {
this.unbindMediaElementEvents();
}
document.removeEventListener('keyup', this.onWindowKeyUp);
document.removeEventListener('touchstart', this.onTouchStart);
if (this._rendition) {
this._rendition.off('keyup', this.onWindowKeyUp);
this._rendition.off('touchstart', this.onTouchStart);
}
}
@ -169,13 +195,11 @@ export class BookPlayer {
createMediaElement() {
let elem = this._mediaElement;
if (elem) {
return elem;
}
elem = document.getElementById('bookPlayer');
if (!elem) {
elem = dialogHelper.createDialog({
exitAnimationDuration: 400,
@ -185,6 +209,7 @@ export class BookPlayer {
exitAnimation: 'fadeout',
removeOnClose: true
});
elem.id = 'bookPlayer';
let html = '';
@ -230,6 +255,7 @@ export class BookPlayer {
let cancellationToken = {
shouldCancel: false
};
this._cancellationToken = cancellationToken;
return rendition.display().then(() => {
@ -253,7 +279,6 @@ export class BookPlayer {
epubElem.style.display = 'block';
rendition.on('relocated', (locations) => {
this._progress = book.locations.percentageFromCfi(locations.start.cfi);
events.trigger(this, 'timeupdate');
});
@ -262,7 +287,7 @@ export class BookPlayer {
return resolve();
});
}, () => {
console.error('Failed to display epub');
console.error('failed to display epub');
return reject();
});
});

View file

@ -1495,7 +1495,7 @@
"New": "Nové",
"ButtonTogglePlaylist": "Playlist",
"ButtonToggleContextMenu": "Více",
"LabelNightly": "Nightly",
"LabelNightly": "Aktualizace každou noc",
"LabelStable": "Stabilní",
"LabelChromecastVersion": "Verze Chromecastu",
"ApiKeysCaption": "Seznam povolených API klíčů",
@ -1566,5 +1566,6 @@
"StopPlayback": "Zastavit přehrávání",
"ViewAlbumArtist": "Zobrazit interpreta alba",
"PreviousTrack": "Předchozí",
"NextTrack": "Další"
"NextTrack": "Další",
"LabelUnstable": "Nestabilní"
}

View file

@ -1564,5 +1564,8 @@
"StopPlayback": "Arrêter",
"ButtonPlayer": "Démarrer",
"Writers": "Écrivains",
"ViewAlbumArtist": "Voir l'album de l'artiste"
"ViewAlbumArtist": "Voir l'album de l'artiste",
"PreviousTrack": "Revenir au précédent",
"NextTrack": "Passer au prochain",
"LabelUnstable": "Instable"
}

View file

@ -1520,7 +1520,7 @@
"MessageSyncPlayGroupDoesNotExist": "Impossibile unirsi al gruppo perchè non esiste.",
"MessageSyncPlayPlaybackPermissionRequired": "Permesso di riproduzione necessario.",
"MessageSyncPlayNoGroupsAvailable": "Nessun gruppo disponibile. Inizia a riprodurre qualcosa.",
"MessageSyncPlayGroupWait": "<b>{0}</b> sta bufferizzando...",
"MessageSyncPlayGroupWait": "<b>{0}</b> sta bufferizzando",
"MessageSyncPlayUserLeft": "<b>{0}</b> ha lasciato il gruppo.",
"MessageSyncPlayUserJoined": "<b>{0}</b> si è unito al gruppo.",
"MessageSyncPlayDisabled": "SyncPlay disabilitato.",
@ -1564,5 +1564,6 @@
"ViewAlbumArtist": "Visualizza artista dell'album",
"Writers": "Scrittori",
"ClearQueue": "Svuota la coda",
"StopPlayback": "Interrompi riproduzione"
"StopPlayback": "Interrompi riproduzione",
"LabelUnstable": "Unstable"
}

View file

@ -76,7 +76,7 @@
"ButtonEditImages": "イメージを編集",
"ButtonEditOtherUserPreferences": "ユーザーのアバターイメージやプロフィールなどの個人設定を編集。",
"ButtonFilter": "フィルタ",
"ButtonForgotPassword": "パスワードを忘れました",
"ButtonForgotPassword": "パスワードを忘れた",
"ButtonFullscreen": "フルスクリーン",
"ButtonGotIt": "了解",
"ButtonGuide": "ガイド",
@ -502,7 +502,7 @@
"ButtonAddImage": "イメージの追加",
"List": "リスト",
"MediaInfoTimestamp": "タイムスタンプ",
"NoSubtitles": "字幕がありません",
"NoSubtitles": "無し",
"TabCollections": "コレクション",
"Thursday": "木曜日",
"TitleHardwareAcceleration": "ハードウェアアクセラレーション",

View file

@ -813,7 +813,7 @@
"AllowOnTheFlySubtitleExtraction": "실시간 자막 추출 허용",
"AllowOnTheFlySubtitleExtractionHelp": "비디오 트랜스코딩을 방지하기 위해 내장된 자막을 비디오에서 추출하여 텍스트로 클라이언트에 전송할 수 있습니다. 다만, 일부 시스템에서 추출 과정은 긴 시간이 걸리고 비디오 재생을 멈출 수 있습니다. 클라이언트에서 트랜스코딩을 사용할 수 없는 경우 이 기능을 비활성화하여 트랜스코딩 시 자막을 영상에 삽입하십시오.",
"AllowRemoteAccess": "이 Jellyfin 서버에 원격 접속을 허용합니다.",
"AllowRemoteAccessHelp": "체크 해제 시 모든 외부 접속은 차단됩니다.",
"AllowRemoteAccessHelp": "비 활성화할 시, 모든 외부 접속은 차단됩니다.",
"AllowedRemoteAddressesHelp": "외부 접속을 허용할 IP 혹은 IP 넷마스크를 반점(,)으로 구분하여 입력하십시오. 공란일시, 모든 외부 접속이 허용됩니다.",
"AlwaysPlaySubtitles": "항상 표시",
"AlwaysPlaySubtitlesHelp": "오디오 언어를 불문하고 언어 설정에 적합한 자막을 불러옵니다.",

View file

@ -90,7 +90,7 @@
"ButtonMore": "Więcej",
"ButtonNetwork": "Sieć",
"ButtonNew": "Nowe",
"ButtonNextTrack": "Następna utwór",
"ButtonNextTrack": "Następny utwór",
"ButtonOff": "Wyłącz",
"ButtonOpen": "Otwórz",
"ButtonParentalControl": "Kontrola rodzicielska",
@ -1564,5 +1564,8 @@
"EnableDetailsBanner": "Baner w szczegółach",
"EnableDecodingColorDepth10Vp9": "Włącz 10-bitowe dekodowanie sprzętowe dla VP9",
"EnableDecodingColorDepth10Hevc": "Włącz 10-bitowe dekodowanie sprzętowe dla HEVC",
"BoxSet": "Kolekcja"
"BoxSet": "Kolekcja",
"PreviousTrack": "Poprzedni",
"NextTrack": "Następny",
"LabelUnstable": "Niestabilny"
}

View file

@ -1521,7 +1521,7 @@
"MessageSyncPlayGroupDoesNotExist": "Falha ao participar de grupo pois o mesmo não existe.",
"MessageSyncPlayPlaybackPermissionRequired": "É necessária permissão de reprodução.",
"MessageSyncPlayNoGroupsAvailable": "Nenhum grupo disponível. Comece a reproduzir algo primeiro.",
"MessageSyncPlayGroupWait": "<b>{0}</b> está carregando. . .",
"MessageSyncPlayGroupWait": "<b>{0}</b> está carregando",
"MessageSyncPlayUserLeft": "<b>{0}</b> deixou o grupo.",
"MessageSyncPlayUserJoined": "<b>{0}</b> se juntou ao grupo.",
"MessageSyncPlayDisabled": "SyncPlay desativado.",
@ -1564,5 +1564,8 @@
"Writers": "Escritores",
"ClearQueue": "Limpar fila",
"StopPlayback": "Parar reprodução",
"ViewAlbumArtist": "Ver artista do álbum"
"ViewAlbumArtist": "Ver artista do álbum",
"PreviousTrack": "Ir para o anterior",
"NextTrack": "Ir para o próximo",
"LabelUnstable": "Instável"
}