| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 | import { appInit } from '../actions';
import { AbstractApp } from './AbstractApp';
/**
 * 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);
        this.state = {
            ...this.state,
            /**
             * The context root of window.location i.e. this Web App.
             *
             * @type {string}
             */
            windowLocationContextRoot: this._getWindowLocationContextRoot()
        };
    }
    /**
     * Inits the app before component will mount.
     *
     * @inheritdoc
     */
    componentWillMount(...args) {
        super.componentWillMount(...args);
        this._getStore().dispatch(appInit());
    }
    /**
     * Gets a Location object from the window with information about the current
     * location of the document.
     *
     * @inheritdoc
     */
    _getWindowLocation() {
        return window.location;
    }
    /**
     * Gets the context root of this Web App from window.location.
     *
     * @private
     * @returns {string} The context root of window.location i.e. this Web App.
     */
    _getWindowLocationContextRoot() {
        const pathname = this._getWindowLocation().pathname;
        const contextRootEndIndex = pathname.lastIndexOf('/');
        return (
            contextRootEndIndex === -1
                ? '/'
                : pathname.substring(0, contextRootEndIndex + 1));
    }
    /**
     * Navigates to a specific Route (via platform-specific means).
     *
     * @param {Route} route - The Route to which to navigate.
     * @protected
     * @returns {void}
     */
    _navigate(route) {
        let path = route.path;
        const store = this._getStore();
        // 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);
        path = this._routePath2WindowLocationPathname(path);
        // Navigate to the specified Route.
        const windowLocation = this._getWindowLocation();
        if (windowLocation.pathname === path) {
            // The browser is at the specified path already and what remains is
            // to make this App instance aware of the route to be rendered at
            // the current location.
            super._navigate(route);
        } else {
            // The browser must go to the specified location. Once the specified
            // location becomes current, the App will be made aware of the route
            // to be rendered at it.
            windowLocation.pathname = path;
        }
    }
    /**
     * Converts a specific Route path to a window.location.pathname.
     *
     * @param {string} path - A Route path to be converted to/represeted as a
     * window.location.pathname.
     * @private
     * @returns {string} A window.location.pathname-compatible representation of
     * the specified Route path.
     */
    _routePath2WindowLocationPathname(path) {
        let pathname = this.state.windowLocationContextRoot;
        pathname.endsWith('/') || (pathname += '/');
        pathname += path.startsWith('/') ? path.substring(1) : path;
        return pathname;
    }
}
 |