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

216 lines
7 KiB
React
Raw Normal View History

2024-08-14 13:49:41 -04:00
// Import legacy browser polyfills
2024-08-14 12:51:54 -04:00
import 'lib/legacy';
import React from 'react';
2024-06-02 20:58:11 +03:00
import { createRoot } from 'react-dom/client';
2024-08-14 13:31:34 -04:00
2024-08-14 13:49:41 -04:00
// NOTE: We need to import this first to initialize the connection
2022-09-29 12:50:25 -04:00
import ServerConnections from './components/ServerConnections';
2024-08-14 13:49:41 -04:00
2022-09-29 12:50:25 -04:00
import { appHost } from './components/apphost';
2024-08-14 13:49:41 -04:00
import autoFocuser from './components/autoFocuser';
2024-09-04 17:06:37 -04:00
import loading from 'components/loading/loading';
2024-08-14 13:49:41 -04:00
import { pluginManager } from './components/pluginManager';
import { appRouter } from './components/router/appRouter';
2024-08-14 13:49:41 -04:00
import globalize from './lib/globalize';
2024-08-14 13:31:34 -04:00
import { loadCoreDictionary } from 'lib/globalize/loader';
import { initialize as initializeAutoCast } from 'scripts/autocast';
2024-08-14 13:49:41 -04:00
import browser from './scripts/browser';
import keyboardNavigation from './scripts/keyboardNavigation';
import { getPlugins } from './scripts/settings/webSettings';
2022-09-29 12:50:25 -04:00
import taskButton from './scripts/taskbutton';
2024-08-14 13:49:41 -04:00
import { pageClassOn, serverAddress } from './utils/dashboard';
import Events from './utils/events';
import RootApp from './RootApp';
import { history } from 'RootAppRouter';
2020-08-14 06:36:46 +02:00
2024-08-14 13:49:41 -04:00
// Import the button webcomponent for use throughout the site
// NOTE: This is a bit of a hack, files should ensure the component is imported before use
import './elements/emby-button/emby-button';
// Import auto-running components
// NOTE: This is an anti-pattern
import './components/playback/displayMirrorManager';
import './components/playback/playerSelectionMenu';
import './components/themeMediaPlayer';
import './scripts/autoThemes';
import './scripts/mouseManager';
import './scripts/screensavermanager';
import './scripts/serverNotifications';
// Import site styles
import './styles/site.scss';
2023-03-01 09:35:21 -05:00
import './styles/livetv.scss';
import './styles/dashboard.scss';
import './styles/detailtable.scss';
2024-08-14 13:49:41 -04:00
import './styles/librarybrowser.scss';
2023-03-01 09:35:21 -05:00
2024-08-14 16:00:16 -04:00
async function init() {
// Log current version to console to help out with issue triage and debugging
2024-05-17 17:22:55 -04:00
console.info(
`[${__PACKAGE_JSON_NAME__}]
version: ${__PACKAGE_JSON_VERSION__}
commit: ${__COMMIT_SHA__}
build: ${__JF_BUILD_VERSION__}`);
2024-08-14 16:00:16 -04:00
// Register globals 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;
2024-08-14 16:33:25 -04:00
// Register handlers to update header classes
pageClassOn('viewshow', 'standalonePage', function () {
document.querySelector('.skinHeader').classList.add('noHeaderRight');
});
pageClassOn('viewhide', 'standalonePage', function () {
document.querySelector('.skinHeader').classList.remove('noHeaderRight');
});
2024-08-14 16:00:16 -04:00
// Initialize the api client
const serverUrl = await serverAddress();
if (serverUrl) {
ServerConnections.initApiClient(serverUrl);
}
2024-08-14 16:00:16 -04:00
// Initialize automatic (default) cast target
2024-09-08 13:53:29 +03:00
initializeAutoCast();
2024-08-14 16:00:16 -04:00
// Load the translation dictionary
await loadCoreDictionary();
// Update localization on user changes
Events.on(ServerConnections, 'localusersignedin', globalize.updateCurrentCulture);
Events.on(ServerConnections, 'localusersignedout', globalize.updateCurrentCulture);
// Localize the document title
document.title = globalize.translateHtml(document.title, 'core');
// Load the font styles
loadFonts();
// Load iOS specific styles
if (browser.iOS) {
import('./styles/ios.scss');
}
2024-08-14 16:00:16 -04:00
// Load frontend plugins
await loadPlugins();
2018-10-23 01:05:09 +03:00
2024-08-14 16:00:16 -04:00
// Establish the websocket connection
Events.on(appHost, 'resume', () => {
ServerConnections.currentApiClient()?.ensureWebSocket();
});
2018-10-23 01:05:09 +03:00
2024-09-04 17:06:37 -04:00
// Register API request error handlers
ServerConnections.getApiClients().forEach(apiClient => {
Events.off(apiClient, 'requestfail', appRouter.onRequestFail);
Events.on(apiClient, 'requestfail', appRouter.onRequestFail);
});
Events.on(ServerConnections, 'apiclientcreated', (_e, apiClient) => {
Events.off(apiClient, 'requestfail', appRouter.onRequestFail);
Events.on(apiClient, 'requestfail', appRouter.onRequestFail);
});
2024-08-14 16:00:16 -04:00
// Render the app
await renderApp();
2020-04-03 18:49:19 +02:00
2024-08-14 16:00:16 -04:00
// Load platform specific features
loadPlatformFeatures();
2018-10-23 01:05:09 +03:00
2024-08-14 16:00:16 -04:00
// Enable navigation controls
keyboardNavigation.enable();
autoFocuser.enable();
}
function loadFonts() {
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');
} else if (__USE_SYSTEM_FONTS__) {
2023-09-17 00:41:40 +03:00
console.debug('using system fonts');
import('./styles/fonts.scss');
2020-10-18 20:00:39 +01:00
} else {
console.debug('using default fonts');
import('./styles/fonts.scss');
2023-09-17 00:41:40 +03:00
import('./styles/fonts.noto.scss');
}
2020-10-18 20:00:39 +01:00
}
2024-08-14 16:22:40 -04:00
async function loadPlugins() {
2020-10-18 20:00:39 +01:00
console.groupCollapsed('loading installed plugins');
console.dir(pluginManager);
2024-08-14 16:22:40 -04:00
let list = await getPlugins();
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'));
}
// add any native plugins
if (window.NativeShell) {
list = list.concat(window.NativeShell.getPlugins());
}
try {
await Promise.all(list.map(plugin => pluginManager.loadPlugin(plugin)));
console.debug('finished loading plugins');
} catch (e) {
console.warn('failed loading plugins', e);
}
console.groupEnd('loading installed plugins');
2020-10-18 20:00:39 +01:00
}
2024-08-14 16:00:16 -04:00
function loadPlatformFeatures() {
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
}
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');
}
}
2024-08-14 16:00:16 -04:00
}
2020-10-18 20:00:39 +01:00
function registerServiceWorker() {
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-07-19 16:15:11 +02:00
}
2024-08-14 16:00:16 -04:00
async function renderApp() {
const container = document.getElementById('reactRoot');
// Remove the splash logo
container.innerHTML = '';
2024-09-04 17:06:37 -04:00
loading.show();
2024-08-14 16:00:16 -04:00
const root = createRoot(container);
root.render(
<RootApp history={history} />
2024-08-14 16:00:16 -04:00
);
}
2020-10-18 20:00:39 +01:00
init();