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

275 lines
9.3 KiB
React
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';
2020-08-14 08:46:34 +02:00
import 'classlist.js';
2020-08-14 06:36:46 +02:00
import 'whatwg-fetch';
import 'resize-observer-polyfill';
import './styles/site.scss';
2022-10-18 00:18:54 -04:00
import React, { StrictMode } from 'react';
2022-04-14 01:19:27 -04:00
import * as ReactDOM from 'react-dom';
import Events from './utils/events.ts';
2022-09-29 12:50:25 -04:00
import ServerConnections from './components/ServerConnections';
import globalize from './scripts/globalize';
import browser from './scripts/browser';
import keyboardNavigation from './scripts/keyboardNavigation';
import './scripts/mouseManager';
import autoFocuser from './components/autoFocuser';
import { appHost } from './components/apphost';
import { getPlugins } from './scripts/settings/webSettings';
import { pluginManager } from './components/pluginManager';
import packageManager from './components/packageManager';
import { appRouter, history } from './components/appRouter';
import './elements/emby-button/emby-button';
import './scripts/autoThemes';
import './components/themeMediaPlayer';
import { pageClassOn, serverAddress } from './utils/dashboard';
import './scripts/screensavermanager';
import './scripts/serverNotifications';
import './components/playback/playerSelectionMenu';
import './legacy/domParserTextHtml';
import './legacy/focusPreventScroll';
import './legacy/htmlMediaElement';
import './legacy/vendorStyles';
import { currentSettings } from './scripts/settings/userSettings';
import taskButton from './scripts/taskbutton';
2023-04-27 17:04:33 -04:00
import RootApp from './RootApp.tsx';
2020-08-14 06:36:46 +02:00
2023-03-01 09:35:21 -05:00
import './styles/livetv.scss';
import './styles/dashboard.scss';
import './styles/detailtable.scss';
2020-10-18 20:00:39 +01:00
function loadCoreDictionary() {
const languages = ['af', 'ar', 'be-by', 'bg-bg', 'bn_bd', 'ca', 'cs', 'cy', 'da', 'de', 'el', 'en-gb', 'en-us', 'eo', 'es', 'es_419', 'es-ar', 'es_do', 'es-mx', 'et', 'eu', 'fa', 'fi', 'fil', 'fr', 'fr-ca', 'gl', 'gsw', 'he', 'hi-in', 'hr', 'hu', 'id', 'it', 'ja', 'kk', 'ko', 'lt-lt', 'lv', 'mr', 'ms', 'nb', 'nl', 'nn', 'pl', 'pr', 'pt', 'pt-br', 'pt-pt', 'ro', 'ru', 'sk', 'sl-si', 'sq', 'sv', 'ta', 'th', 'tr', 'uk', 'ur_pk', 'vi', 'zh-cn', 'zh-hk', 'zh-tw'];
2020-10-18 20:00:39 +01:00
const translations = languages.map(function (language) {
return {
lang: language,
path: language + '.json'
};
});
2020-10-18 20:00:39 +01:00
globalize.defaultModule('core');
return globalize.loadStrings({
name: 'core',
translations: translations
});
2020-10-18 20:00:39 +01:00
}
2020-10-18 20:00:39 +01:00
function init() {
2021-06-14 03:19:22 +03:00
// This is used in plugins
2021-09-08 02:46:43 +03:00
window.Events = Events;
2021-06-14 03:19:22 +03:00
window.TaskButton = taskButton;
serverAddress().then(server => {
if (server) {
ServerConnections.initApiClient(server);
}
}).then(() => {
console.debug('initAfterDependencies promises resolved');
loadCoreDictionary().then(function () {
onGlobalizeInit();
});
keyboardNavigation.enable();
autoFocuser.enable();
2018-10-23 01:05:09 +03:00
Events.on(ServerConnections, 'localusersignedin', globalize.updateCurrentCulture);
2023-01-26 00:08:41 +03:00
Events.on(ServerConnections, 'localusersignedout', globalize.updateCurrentCulture);
});
2020-10-18 20:00:39 +01:00
}
2018-10-23 01:05:09 +03:00
2020-10-18 20:00:39 +01:00
function onGlobalizeInit() {
2022-10-03 14:22:02 -04:00
if (window.appMode === 'android'
&& window.location.href.toString().toLowerCase().indexOf('start=backgroundsync') !== -1
) {
return onAppReady();
2020-04-03 18:49:19 +02:00
}
2020-10-18 20:00:39 +01:00
document.title = globalize.translateHtml(document.title, 'core');
2018-10-23 01:05:09 +03:00
2020-10-18 20:00:39 +01:00
if (browser.tv && !browser.android) {
console.debug('using system fonts with explicit sizes');
import('./styles/fonts.sized.scss');
2020-10-18 20:00:39 +01:00
} else {
console.debug('using default fonts');
import('./styles/fonts.scss');
}
import('./styles/librarybrowser.scss');
2022-10-01 02:39:12 -04:00
loadPlugins().then(onAppReady);
2020-10-18 20:00:39 +01:00
}
function loadPlugins() {
2020-10-18 20:00:39 +01:00
console.groupCollapsed('loading installed plugins');
console.dir(pluginManager);
return getPlugins().then(function (list) {
if (!appHost.supports('remotecontrol')) {
// Disable remote player plugins if not supported
list = list.filter(plugin => !plugin.startsWith('sessionPlayer')
&& !plugin.startsWith('chromecastPlayer'));
} else if (!browser.chrome && !browser.edgeChromium && !browser.opera) {
// Disable chromecast player in unsupported browsers
list = list.filter(plugin => !plugin.startsWith('chromecastPlayer'));
2019-01-21 17:47:10 +09:00
}
2020-10-18 20:00:39 +01:00
// add any native plugins
if (window.NativeShell) {
list = list.concat(window.NativeShell.getPlugins());
}
2018-10-23 01:05:09 +03:00
Promise.all(list.map(plugin => pluginManager.loadPlugin(plugin)))
.then(() => console.debug('finished loading plugins'))
.catch(e => console.warn('failed loading plugins', e))
2020-10-18 20:00:39 +01:00
.finally(() => {
console.groupEnd('loading installed plugins');
packageManager.init();
})
;
});
}
async function onAppReady() {
2020-10-18 20:00:39 +01:00
console.debug('begin onAppReady');
2020-08-08 15:26:03 +02:00
2020-10-18 20:00:39 +01:00
console.debug('onAppReady: loading dependencies');
2019-05-05 23:55:42 +02:00
2020-10-18 20:00:39 +01:00
if (browser.iOS) {
import('./styles/ios.scss');
2018-10-23 01:05:09 +03:00
}
Events.on(appHost, 'resume', () => {
ServerConnections.currentApiClient()?.ensureWebSocket();
});
2022-11-18 18:58:11 -05:00
const root = document.getElementById('reactRoot');
// Remove the splash logo
root.innerHTML = '';
2022-04-14 01:19:27 -04:00
await appRouter.start();
ReactDOM.render(
2022-10-18 00:18:54 -04:00
<StrictMode>
2023-04-27 17:04:33 -04:00
<RootApp history={history} />
2022-10-18 00:18:54 -04:00
</StrictMode>,
2022-11-18 18:58:11 -05:00
root
2022-04-14 01:19:27 -04:00
);
2020-08-09 15:03:41 +02:00
if (!browser.tv && !browser.xboxOne && !browser.ps4) {
2022-09-29 12:50:25 -04:00
import('./components/nowPlayingBar/nowPlayingBar');
2018-10-23 01:05:09 +03:00
}
if (appHost.supports('remotecontrol')) {
2022-09-29 12:50:25 -04:00
import('./components/playback/playerSelectionMenu');
import('./components/playback/remotecontrolautoplay');
2018-10-23 01:05:09 +03:00
}
if (!appHost.supports('physicalvolumecontrol') || browser.touch) {
2022-09-29 12:50:25 -04:00
import('./components/playback/volumeosd');
2018-10-23 01:05:09 +03:00
}
/* eslint-disable-next-line compat/compat */
if (navigator.mediaSession || window.NativeShell) {
2022-09-29 12:50:25 -04:00
import('./components/playback/mediasession');
}
2019-11-23 23:25:10 +03:00
if (!browser.tv && !browser.xboxOne) {
2022-09-29 12:50:25 -04:00
import('./components/playback/playbackorientation');
registerServiceWorker();
if (window.Notification) {
2022-09-29 12:50:25 -04:00
import('./components/notifications/notifications');
}
}
const apiClient = ServerConnections.currentApiClient();
if (apiClient) {
const updateStyle = (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;
};
const style = fetch(apiClient.getUrl('Branding/Css'))
.then(function(response) {
if (!response.ok) {
throw new Error(response.status + ' ' + response.statusText);
}
return response.text();
})
.catch(function(err) {
console.warn('Error applying custom css', err);
});
const handleStyleChange = async () => {
if (currentSettings.disableCustomCss()) {
updateStyle('');
} else {
updateStyle(await style);
}
const localCss = currentSettings.customCss();
let localStyle = document.querySelector('#localCssBranding');
if (localCss) {
if (!localStyle) {
// Inject the branding css as a dom element in body so it will take
// precedence over other stylesheets
localStyle = document.createElement('style');
localStyle.id = 'localCssBranding';
document.body.appendChild(localStyle);
}
localStyle.textContent = localCss;
} else {
if (localStyle) {
localStyle.textContent = '';
}
}
};
const handleUserChange = () => {
handleStyleChange();
};
Events.on(ServerConnections, 'localusersignedin', handleUserChange);
Events.on(ServerConnections, 'localusersignedout', handleUserChange);
Events.on(currentSettings, 'change', (e, prop) => {
if (prop == 'disableCustomCss' || prop == 'customCss') {
handleStyleChange();
}
});
style.then(updateStyle);
2018-10-23 01:05:09 +03:00
}
2020-10-18 20:00:39 +01:00
}
2018-10-23 01:05:09 +03:00
2020-10-18 20:00:39 +01:00
function registerServiceWorker() {
/* eslint-disable compat/compat */
if (navigator.serviceWorker && window.appMode !== 'cordova' && window.appMode !== 'android') {
2021-05-18 23:22:57 +03:00
navigator.serviceWorker.register('serviceworker.js').then(() =>
2020-12-16 13:57:07 -05:00
console.log('serviceWorker registered')
).catch(error =>
console.log('error registering serviceWorker: ' + error)
);
2020-10-18 20:00:39 +01:00
} else {
console.warn('serviceWorker unsupported');
2018-10-23 01:05:09 +03:00
}
2020-10-18 20:00:39 +01:00
/* eslint-enable compat/compat */
2020-07-19 16:15:11 +02:00
}
2020-10-18 20:00:39 +01:00
init();
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
});