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

396 lines
15 KiB
JavaScript
Raw Normal View History

2020-08-14 06:36:46 +02:00
import 'core-js/stable';
import 'regenerator-runtime/runtime';
import 'jquery';
import 'fast-text-encoding';
import 'intersection-observer';
import 'classlist-polyfill';
import 'whatwg-fetch';
import 'resize-observer-polyfill';
import 'jellyfin-noto';
import '../assets/css/site.css';
// TODO: Move this elsewhere
2020-08-08 15:26:03 +02:00
window.getWindowLocationSearch = function(win) {
2020-10-07 21:12:14 +09:00
let search = (win || window).location.search;
2018-10-23 01:05:09 +03:00
if (!search) {
2020-10-07 21:12:14 +09:00
const index = window.location.href.indexOf('?');
2020-07-30 16:07:13 +02:00
if (index != -1) {
search = window.location.href.substring(index);
}
2018-10-23 01:05:09 +03:00
}
2020-05-04 12:44:12 +02:00
return search || '';
2020-08-08 15:26:03 +02:00
};
2018-10-23 01:05:09 +03:00
2020-08-14 06:36:46 +02:00
// TODO: Move this elsewhere
2020-08-08 15:26:03 +02:00
window.getParameterByName = function(name, url) {
2020-05-04 12:44:12 +02:00
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
2020-10-07 21:12:14 +09:00
const regexS = '[\\?&]' + name + '=([^&#]*)';
const regex = new RegExp(regexS, 'i');
const results = regex.exec(url || getWindowLocationSearch());
2020-07-30 16:07:13 +02:00
if (results == null) {
2020-05-04 12:44:12 +02:00
return '';
}
2020-05-04 12:44:12 +02:00
return decodeURIComponent(results[1].replace(/\+/g, ' '));
2020-07-19 16:15:11 +02:00
};
2018-10-23 01:05:09 +03:00
2020-08-14 06:36:46 +02:00
// TODO: Move this elsewhere
2020-08-08 15:26:03 +02:00
window.pageClassOn = function(eventName, className, fn) {
2019-03-04 20:38:39 +00:00
document.addEventListener(eventName, function (event) {
2020-10-07 21:12:14 +09:00
const target = event.target;
if (target.classList.contains(className)) {
2019-03-04 20:38:39 +00:00
fn.call(target, event);
}
});
2020-08-08 15:26:03 +02:00
};
2018-10-23 01:05:09 +03:00
2020-08-14 06:36:46 +02:00
// TODO: Move this elsewhere
2020-07-19 16:15:11 +02:00
window.pageIdOn = function(eventName, id, fn) {
2019-03-04 20:38:39 +00:00
document.addEventListener(eventName, function (event) {
2020-10-07 21:12:14 +09:00
const target = event.target;
if (target.id === id) {
2019-03-04 20:38:39 +00:00
fn.call(target, event);
}
});
};
2020-10-07 21:12:14 +09:00
const AppInfo = {};
2020-07-19 16:15:11 +02:00
function initClient() {
2018-10-23 01:05:09 +03:00
function bindConnectionManagerEvents(connectionManager, events, userSettings) {
window.Events = events;
2020-08-30 06:06:47 +02:00
window.connectionManager.currentApiClient = function () {
2018-10-23 01:05:09 +03:00
if (!localApiClient) {
2020-10-07 21:12:14 +09:00
const server = window.connectionManager.getLastUsedServer();
if (server) {
2020-08-30 06:06:47 +02:00
localApiClient = window.connectionManager.getApiClient(server.Id);
}
2018-10-23 01:05:09 +03:00
}
return localApiClient;
};
2020-08-30 06:06:47 +02:00
window.connectionManager.onLocalUserSignedIn = function (user) {
localApiClient = window.connectionManager.getApiClient(user.ServerId);
window.ApiClient = localApiClient;
return userSettings.setUserInfo(user.Id, localApiClient);
};
2020-05-04 12:44:12 +02:00
events.on(connectionManager, 'localusersignedout', function () {
userSettings.setUserInfo(null, null);
});
2018-10-23 01:05:09 +03:00
}
function createConnectionManager() {
2020-08-14 06:36:46 +02:00
return Promise.all([
import('jellyfin-apiclient/src/connectionManager'),
import('../components/apphost'),
import('jellyfin-apiclient/src/connectionManager'),
import('jellyfin-apiclient/src/events'),
import('./settings/userSettings')
])
.then(([ConnectionManager, appHost, credentialProvider, events, userSettings]) => {
appHost = appHost.default || appHost;
2020-08-09 15:03:41 +02:00
2020-08-14 06:36:46 +02:00
const credentialProviderInstance = new credentialProvider();
const promises = [appHost.init()];
2020-08-14 06:36:46 +02:00
return Promise.all(promises).then(function (responses) {
const capabilities = Dashboard.capabilities(appHost);
2020-08-14 06:36:46 +02:00
window.ConnectionManager = new ConnectionManager(credentialProviderInstance, appHost.appName(), appHost.appVersion(), appHost.deviceName(), appHost.deviceId(), capabilities);
2020-08-14 06:36:46 +02:00
bindConnectionManagerEvents(window.ConnectionManager, events, userSettings);
2020-08-14 06:36:46 +02:00
if (!AppInfo.isNativeApp) {
console.debug('loading ApiClient singleton');
2020-08-14 06:36:46 +02:00
return Promise.all([
import('jellyfin-apiclient/src/apiClient'),
import('./clientUtils')
])
.then(([apiClientFactory, clientUtils]) => {
console.debug('creating ApiClient singleton');
2020-08-14 06:36:46 +02:00
var apiClient = new apiClientFactory(Dashboard.serverAddress(), appHost.appName(), appHost.appVersion(), appHost.deviceName(), appHost.deviceId());
2019-03-17 22:24:49 +01:00
2020-08-14 06:36:46 +02:00
apiClient.enableAutomaticNetworking = false;
apiClient.manualAddressOnly = true;
2020-08-14 06:36:46 +02:00
window.ConnectionManager.addApiClient(apiClient);
2020-08-14 06:36:46 +02:00
window.ApiClient = apiClient;
localApiClient = apiClient;
2020-08-14 06:36:46 +02:00
console.debug('loaded ApiClient singleton');
});
}
2018-10-23 01:05:09 +03:00
2020-08-14 06:36:46 +02:00
return Promise.resolve();
});
});
2018-10-23 01:05:09 +03:00
}
function init() {
2020-08-14 06:36:46 +02:00
import('./clientUtils')
.then(function () {
createConnectionManager().then(function () {
console.debug('initAfterDependencies promises resolved');
Promise.all([
import('./globalize'),
import('./browser')
])
.then(([globalize, {default: browser}]) => {
window.Globalize = globalize;
loadCoreDictionary(globalize).then(function () {
onGlobalizeInit(browser, globalize);
});
});
import('./keyboardNavigation')
.then((keyboardnavigation) => {
keyboardnavigation.enable();
});
import(['./mouseManager']);
import('../components/autoFocuser').then((autoFocuser) => {
autoFocuser.enable();
});
2020-08-14 06:36:46 +02:00
Promise.all([
import('./globalize'),
import('jellyfin-apiclient/src/connectionManager'),
import('jellyfin-apiclient/src/events')
])
.then((globalize, connectionManager, events) => {
events.on(connectionManager, 'localusersignedin', globalize.updateCurrentCulture);
});
});
});
2018-10-23 01:05:09 +03:00
}
function loadCoreDictionary(globalize) {
2020-10-29 15:28:52 +00:00
const languages = ['ar', 'be-by', 'bg-bg', 'ca', 'cs', 'da', 'de', 'el', 'en-gb', 'en-us', 'es', 'es-ar', 'es-mx', 'fa', 'fi', 'fr', 'fr-ca', 'gsw', 'he', 'hi-in', 'hr', 'hu', 'id', 'it', 'ja', 'kk', 'ko', 'lt-lt', 'ms', 'nb', 'nl', 'pl', 'pt-br', 'pt-pt', 'ro', 'ru', 'sk', 'sl-si', 'sv', 'tr', 'uk', 'vi', 'zh-cn', 'zh-hk', 'zh-tw'];
2020-10-07 21:12:14 +09:00
const translations = languages.map(function (language) {
return {
2019-03-04 20:38:39 +00:00
lang: language,
2020-05-04 12:44:12 +02:00
path: 'strings/' + language + '.json'
};
});
2020-05-04 12:44:12 +02:00
globalize.defaultModule('core');
return globalize.loadStrings({
2020-05-04 12:44:12 +02:00
name: 'core',
2018-10-23 01:05:09 +03:00
translations: translations
});
2018-10-23 01:05:09 +03:00
}
2020-07-18 09:21:15 +01:00
function onGlobalizeInit(browser, globalize) {
2020-08-25 10:12:35 +09:00
if (window.appMode === 'android') {
if (window.location.href.toString().toLowerCase().indexOf('start=backgroundsync') !== -1) {
return onAppReady(browser);
}
2018-10-23 01:05:09 +03:00
}
2020-07-18 09:21:15 +01:00
document.title = globalize.translateHtml(document.title, 'core');
if (browser.tv && !browser.android) {
2020-05-04 12:44:12 +02:00
console.debug('using system fonts with explicit sizes');
2020-08-14 06:36:46 +02:00
import('../assets/css/fonts.sized.css');
} else {
2020-05-04 12:44:12 +02:00
console.debug('using default fonts');
2020-08-14 06:36:46 +02:00
import('../assets/css/fonts.css');
}
2020-08-14 06:36:46 +02:00
Promise.all([
import('../components/apphost'),
import('../assets/css/librarybrowser.css')
]).then((appHost) => {
2019-05-21 22:28:48 +01:00
loadPlugins(appHost, browser).then(function () {
2019-01-21 17:47:10 +09:00
onAppReady(browser);
});
});
2018-10-23 01:05:09 +03:00
}
2019-05-21 22:28:48 +01:00
function loadPlugins(appHost, browser, shell) {
2020-08-01 03:01:32 +02:00
console.groupCollapsed('loading installed plugins');
return new Promise(function (resolve, reject) {
2020-08-14 06:36:46 +02:00
import('./settings/webSettings')
.then((webSettings) => {
webSettings.getPlugins().then(function (list) {
// these two plugins are dependent on features
if (!appHost.supports('remotecontrol')) {
list.splice(list.indexOf('sessionPlayer'), 1);
if (!browser.chrome && !browser.opera) {
list.splice(list.indexOf('chromecastPlayer', 1));
}
}
2020-08-14 06:36:46 +02:00
// add any native plugins
if (window.NativeShell) {
list = list.concat(window.NativeShell.getPlugins());
}
2020-08-14 06:36:46 +02:00
Promise.all(list.map(loadPlugin))
.then(function () {
console.debug('finished loading plugins');
})
.catch(() => reject)
.finally(() => {
console.groupEnd('loading installed plugins');
import('../components/packageManager')
.then((packageManager) => {
packageManager.default.init().then(resolve, reject);
});
})
;
});
});
});
2018-10-23 01:05:09 +03:00
}
function loadPlugin(url) {
return new Promise(function (resolve, reject) {
2020-08-14 06:36:46 +02:00
import('pluginManager')
.then((pluginManager) => {
pluginManager.default.loadPlugin(url).then(resolve, reject);
});
});
2018-10-23 01:05:09 +03:00
}
function onAppReady(browser) {
2020-05-04 12:44:12 +02:00
console.debug('begin onAppReady');
// ensure that appHost is loaded in this point
2020-08-14 06:36:46 +02:00
Promise.all([
import('jellyfin-apiclient/src/apiClient'),
import('../components/appRouter')
])
.then(([appHost, appRouter]) => {
appRouter = appRouter.default || appRouter;
appHost = appHost.default || appHost;
window.Emby = {};
console.debug('onAppReady: loading dependencies');
if (browser.iOS) {
import('../assets/css/ios.css');
}
2020-08-14 06:36:46 +02:00
window.Emby.Page = appRouter;
Promise.all([
import('../elements/emby-button/emby-button'),
import('./autoThemes'),
import('./libraryMenu'),
import('./routes')
])
.then(() => {
Emby.Page.start({
click: false,
hashbang: true
});
2020-08-14 06:36:46 +02:00
import('../components/themeMediaPlayer');
import('./autoBackdrops');
2020-08-14 06:36:46 +02:00
if (!browser.tv && !browser.xboxOne && !browser.ps4) {
import('../components/nowPlayingBar/nowPlayingBar');
}
2020-08-14 06:36:46 +02:00
if (appHost.supports('remotecontrol')) {
import('../components/playback/playerSelectionMenu');
import('../components/playback/remotecontrolautoplay');
}
2019-11-23 23:25:10 +03:00
2020-08-14 06:36:46 +02:00
import('../libraries/screensavermanager');
2020-08-14 06:36:46 +02:00
if (!appHost.supports('physicalvolumecontrol') || browser.touch) {
import('../components/playback/volumeosd');
}
2020-08-14 06:36:46 +02:00
/* eslint-disable-next-line compat/compat */
if (navigator.mediaSession || window.NativeShell) {
import('../components/playback/mediasession');
}
2020-08-14 06:36:46 +02:00
import('./serverNotifications');
2020-08-14 06:36:46 +02:00
if (!browser.tv && !browser.xboxOne) {
import('../components/playback/playbackorientation');
registerServiceWorker();
2020-08-14 06:36:46 +02:00
if (window.Notification) {
import('../components/notifications/notifications');
2020-08-13 00:15:02 +03:00
}
2020-08-14 06:36:46 +02:00
}
import('../components/playback/playerSelectionMenu');
const apiClient = window.ConnectionManager && window.ConnectionManager.currentApiClient();
if (apiClient) {
fetch(apiClient.getUrl('Branding/Css'))
.then(function(response) {
if (!response.ok) {
throw new Error(response.status + ' ' + response.statusText);
}
return response.text();
})
.then(function(css) {
let style = document.querySelector('#cssBranding');
if (!style) {
// Inject the branding css as a dom element in body so it will take
// precedence over other stylesheets
style = document.createElement('style');
style.id = 'cssBranding';
document.body.appendChild(style);
}
style.textContent = css;
})
.catch(function(err) {
console.warn('Error applying custom css', err);
});
}
});
});
2018-10-23 01:05:09 +03:00
}
function registerServiceWorker() {
/* eslint-disable compat/compat */
2020-08-25 10:12:35 +09:00
if (navigator.serviceWorker && window.appMode !== 'cordova' && window.appMode !== 'android') {
try {
2020-05-04 12:44:12 +02:00
navigator.serviceWorker.register('serviceworker.js');
} catch (err) {
2020-05-04 12:44:12 +02:00
console.error('error registering serviceWorker: ' + err);
}
} else {
2020-05-04 12:44:12 +02:00
console.warn('serviceWorker unsupported');
2018-10-23 01:05:09 +03:00
}
/* eslint-enable compat/compat */
2018-10-23 01:05:09 +03:00
}
2020-10-07 21:12:14 +09:00
let localApiClient;
2020-08-14 06:36:46 +02:00
if (self.appMode === 'cordova' || self.appMode === 'android' || self.appMode === 'standalone') {
AppInfo.isNativeApp = true;
2020-07-30 20:34:21 +02:00
}
2020-08-14 06:36:46 +02:00
init();
2020-07-19 16:15:11 +02:00
}
2020-07-19 16:15:11 +02:00
initClient();
2020-05-04 12:44:12 +02:00
pageClassOn('viewshow', 'standalonePage', function () {
document.querySelector('.skinHeader').classList.add('noHeaderRight');
2019-01-21 17:47:10 +09:00
});
2020-05-04 12:44:12 +02:00
pageClassOn('viewhide', 'standalonePage', function () {
document.querySelector('.skinHeader').classList.remove('noHeaderRight');
2018-12-11 00:46:50 -05:00
});