| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- /* global APP, JitsiMeetJS, loggingConfig $ */
- import React from 'react';
- import { Provider } from 'react-redux';
- import { compose } from 'redux';
- import {
- browserHistory,
- Route,
- Router
- } from 'react-router';
- import { push, syncHistoryWithStore } from 'react-router-redux';
-
- import { getDomain } from '../../base/connection';
- import { RouteRegistry } from '../../base/navigator';
-
- import { AbstractApp } from './AbstractApp';
- import settings from '../../../../modules/settings/Settings';
-
-
- import URLProcessor from '../../../../modules/config/URLProcessor';
- import getTokenData from '../../../../modules/tokendata/TokenData';
- import JitsiMeetLogStorage from '../../../../modules/util/JitsiMeetLogStorage';
-
- // eslint-disable-next-line max-len
- import KeyboardShortcut from '../../../../modules/keyboardshortcut/keyboardshortcut';
-
- const Logger = require('jitsi-meet-logger');
- const LogCollector = Logger.LogCollector;
-
-
- /**
- * Root application component.
- *
- * @extends AbstractApp
- */
- export class App extends AbstractApp {
- /**
- * App component's property types.
- *
- * @static
- */
- static propTypes = AbstractApp.propTypes;
-
- /**
- * Initializes a new App instance.
- *
- * @param {Object} props - The read-only React Component props with which
- * the new instance is to be initialized.
- */
- constructor(props) {
- super(props);
-
- /**
- * Create an enhanced history that syncs navigation events with the
- * store.
- * @link https://github.com/reactjs/react-router-redux#how-it-works
- */
- this.history = syncHistoryWithStore(browserHistory, props.store);
-
- // Bind event handlers so they are only bound once for every instance.
- this._onRouteEnter = this._onRouteEnter.bind(this);
- this._routerCreateElement = this._routerCreateElement.bind(this);
- this._getRoute = this._getRoute.bind(this);
- this._getRoutes = this._getRoutes.bind(this);
- }
-
- /**
- * Init translation from old app.
- *
- * @inheritdoc
- */
- componentWillMount(...args) {
- super.componentWillMount(...args);
-
- URLProcessor.setConfigParametersFromUrl();
-
- /* APP.init BEGIN */
-
- /* Init logging BEGIN */
-
- // Adjust logging level
- configureLoggingLevels();
-
- // Create the LogCollector and register it as the global log transport.
- // It is done early to capture as much logs as possible. Captured logs
- // will be cached, before the JitsiMeetLogStorage gets ready (statistics
- // module is initialized).
- if (!APP.logCollector && !loggingConfig.disableLogCollector) {
- APP.logCollector = new LogCollector(new JitsiMeetLogStorage());
- Logger.addGlobalTransport(APP.logCollector);
- JitsiMeetJS.addGlobalLogTransport(APP.logCollector);
- }
-
- /* Init logging BEGIN */
-
- APP.keyboardshortcut = KeyboardShortcut;
- APP.tokenData = getTokenData();
-
- /* APP.init END */
-
- APP.API.init(APP.tokenData.externalAPISettings);
-
- /**
- * Adjusts the logging levels.
- *
- * @private
- * @returns {void}
- */
- function configureLoggingLevels() {
- // NOTE The library Logger is separated from
- // the app loggers, so the levels
- // have to be set in two places
-
- // Set default logging level
- const defaultLogLevel
- = loggingConfig.defaultLogLevel || JitsiMeetJS.logLevels.TRACE;
-
- Logger.setLogLevel(defaultLogLevel);
- JitsiMeetJS.setLogLevel(defaultLogLevel);
-
- // NOTE console was used on purpose here to go around the logging
- // and always print the default logging level to the console
- console.info(`Default logging level set to: ${defaultLogLevel}`);
-
- // Set log level for each logger
- if (loggingConfig) {
- Object.keys(loggingConfig).forEach(loggerName => {
- if (loggerName !== 'defaultLogLevel') {
- const level = loggingConfig[loggerName];
-
- Logger.setLogLevelById(level, loggerName);
- JitsiMeetJS.setLogLevelById(level, loggerName);
- }
- });
- }
- }
-
-
- APP.translation.init(settings.getLanguage());
- }
-
- /**
- * Implements React's {@link Component#render()}.
- *
- * @inheritdoc
- * @returns {ReactElement}
- */
- render() {
-
- return (
- <Provider store = { this.props.store }>
- <Router
- createElement = { this._routerCreateElement }
- history = { this.history }>
- { this._getRoutes() }
- </Router>
- </Provider>
- );
- }
-
- /**
- * Navigates to a specific Route (via platform-specific means).
- *
- * @param {Route} route - The Route to which to navigate.
- * @returns {void}
- */
- _navigate(route) {
- let path = route.path;
- const store = this.props.store;
-
- // The syntax :room bellow is defined by react-router. It "matches a URL
- // segment up to the next /, ?, or #. The matched string is called a
- // param."
- path
- = path.replace(
- /:room/g,
- store.getState()['features/base/conference'].room);
-
- return store.dispatch(push(path));
- }
-
- /**
- * Returns routes for application.
- *
- * @returns {Array}
- * @private
- */
- _getRoutes() {
- const routes = RouteRegistry.getRoutes();
-
- return routes.map(this._getRoute);
- }
-
- /**
- * Method returns route for React Router.
- *
- * @param {Object} route - Object that describes route.
- * @returns {ReactElement}
- * @private
- */
- _getRoute(route) {
- const onEnter = route.onEnter || $.noop;
- const handler = compose(this._onRouteEnter, onEnter);
-
- return (
- <Route
- component = { route.component }
- key = { route.component }
- onEnter = { handler }
- path = { route.path } />
- );
- }
-
- /**
- * Invoked by react-router to notify this App that a Route is about to be
- * rendered.
- *
- * @private
- * @returns {void}
- */
- _onRouteEnter() {
-
- // XXX The following is mandatory. Otherwise, moving back & forward
- // through the browser's history could leave this App on the Conference
- // page without a room name.
-
- // Our Router configuration (at the time of this writing) is such that
- // each Route corresponds to a single URL. Hence, entering into a Route
- // is like opening a URL.
-
- // XXX In order to unify work with URLs in web and native environments,
- // we will construct URL here with correct domain from config.
- const currentDomain = getDomain(this.props.store.getState);
- const url
- = new URL(window.location.pathname, `https://${currentDomain}`)
- .toString();
-
- this._openURL(url);
- }
-
- /**
- * Create a ReactElement from the specified component and props on behalf of
- * the associated Router.
- *
- * @param {Component} component - The component from which the ReactElement
- * is to be created.
- * @param {Object} props - The read-only React Component props with which
- * the ReactElement is to be initialized.
- * @private
- * @returns {ReactElement}
- */
- _routerCreateElement(component, props) {
- return this._createElement(component, props);
- }
- }
|