Remove duplication, simplify, comply with coding style
This commit is contained in:
parent
4d5f82633b
commit
0912dbf130
|
@ -1,4 +1,5 @@
|
||||||
/* global APP, JitsiMeetJS, $, config, interfaceConfig, toastr */
|
/* global APP, JitsiMeetJS, $, config, interfaceConfig, toastr */
|
||||||
|
|
||||||
const logger = require("jitsi-meet-logger").getLogger(__filename);
|
const logger = require("jitsi-meet-logger").getLogger(__filename);
|
||||||
|
|
||||||
var UI = {};
|
var UI = {};
|
||||||
|
|
|
@ -1,17 +1,8 @@
|
||||||
import { setRoom } from '../base/conference';
|
import { setRoom } from '../base/conference';
|
||||||
import {
|
import { getDomain, setDomain } from '../base/connection';
|
||||||
getDomain,
|
import { loadConfig, setConfig } from '../base/lib-jitsi-meet';
|
||||||
setDomain
|
|
||||||
} from '../base/connection';
|
|
||||||
import {
|
|
||||||
loadConfig,
|
|
||||||
setConfig
|
|
||||||
} from '../base/lib-jitsi-meet';
|
|
||||||
|
|
||||||
import {
|
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
|
||||||
APP_WILL_MOUNT,
|
|
||||||
APP_WILL_UNMOUNT
|
|
||||||
} from './actionTypes';
|
|
||||||
import {
|
import {
|
||||||
_getRoomAndDomainFromUrlString,
|
_getRoomAndDomainFromUrlString,
|
||||||
_getRouteToRender,
|
_getRouteToRender,
|
||||||
|
@ -20,9 +11,9 @@ import {
|
||||||
import './reducer';
|
import './reducer';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Temporary solution. Should dispatch actions related to
|
* Temporary solution. Should dispatch actions related to initial settings of
|
||||||
* initial settings of the app like setting log levels,
|
* the app like setting log levels, reading the config parameters from query
|
||||||
* reading the config parameters from query string etc.
|
* string etc.
|
||||||
*
|
*
|
||||||
* @returns {Function}
|
* @returns {Function}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
/* global $ */
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import {
|
import { browserHistory, Route, Router } from 'react-router';
|
||||||
browserHistory,
|
|
||||||
Route,
|
|
||||||
Router
|
|
||||||
} from 'react-router';
|
|
||||||
import { push, syncHistoryWithStore } from 'react-router-redux';
|
import { push, syncHistoryWithStore } from 'react-router-redux';
|
||||||
import { compose } from 'redux';
|
|
||||||
|
|
||||||
import { getDomain } from '../../base/connection';
|
import { getDomain } from '../../base/connection';
|
||||||
import { RouteRegistry } from '../../base/navigator';
|
import { RouteRegistry } from '../../base/navigator';
|
||||||
|
@ -45,9 +39,6 @@ export class App extends AbstractApp {
|
||||||
this.history = syncHistoryWithStore(browserHistory, props.store);
|
this.history = syncHistoryWithStore(browserHistory, props.store);
|
||||||
|
|
||||||
// Bind event handlers so they are only bound once for every instance.
|
// Bind event handlers so they are only bound once for every instance.
|
||||||
this._getRoute = this._getRoute.bind(this);
|
|
||||||
this._getRoutes = this._getRoutes.bind(this);
|
|
||||||
this._onRouteEnter = this._onRouteEnter.bind(this);
|
|
||||||
this._routerCreateElement = this._routerCreateElement.bind(this);
|
this._routerCreateElement = this._routerCreateElement.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,44 +65,14 @@ export class App extends AbstractApp {
|
||||||
<Router
|
<Router
|
||||||
createElement = { this._routerCreateElement }
|
createElement = { this._routerCreateElement }
|
||||||
history = { this.history }>
|
history = { this.history }>
|
||||||
{ this._getRoutes() }
|
{
|
||||||
|
this._renderRoutes()
|
||||||
|
}
|
||||||
</Router>
|
</Router>
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 } />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns routes for application.
|
|
||||||
*
|
|
||||||
* @returns {Array}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_getRoutes() {
|
|
||||||
const routes = RouteRegistry.getRoutes();
|
|
||||||
|
|
||||||
return routes.map(this._getRoute);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigates to a specific Route (via platform-specific means).
|
* Navigates to a specific Route (via platform-specific means).
|
||||||
*
|
*
|
||||||
|
@ -137,10 +98,18 @@ export class App extends AbstractApp {
|
||||||
* Invoked by react-router to notify this App that a Route is about to be
|
* Invoked by react-router to notify this App that a Route is about to be
|
||||||
* rendered.
|
* rendered.
|
||||||
*
|
*
|
||||||
|
* @param {Route} route - The Route that is about to be rendered.
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_onRouteEnter() {
|
_onRouteEnter(route, ...args) {
|
||||||
|
// Notify the route that it is about to be entered.
|
||||||
|
const onEnter = route.onEnter;
|
||||||
|
|
||||||
|
if (typeof onEnter === 'function') {
|
||||||
|
onEnter(...args);
|
||||||
|
}
|
||||||
|
|
||||||
// XXX The following is mandatory. Otherwise, moving back & forward
|
// XXX The following is mandatory. Otherwise, moving back & forward
|
||||||
// through the browser's history could leave this App on the Conference
|
// through the browser's history could leave this App on the Conference
|
||||||
// page without a room name.
|
// page without a room name.
|
||||||
|
@ -159,6 +128,37 @@ export class App extends AbstractApp {
|
||||||
this._openURL(url);
|
this._openURL(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a specific Route (for the purposes of the Router of this App).
|
||||||
|
*
|
||||||
|
* @param {Object} route - The Route to render.
|
||||||
|
* @returns {ReactElement}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_renderRoute(route) {
|
||||||
|
const onEnter = (...args) => {
|
||||||
|
this._onRouteEnter(route, ...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Route
|
||||||
|
component = { route.component }
|
||||||
|
key = { route.component }
|
||||||
|
onEnter = { onEnter }
|
||||||
|
path = { route.path } />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the Routes of the Router of this App.
|
||||||
|
*
|
||||||
|
* @returns {Array.<ReactElement>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_renderRoutes() {
|
||||||
|
return RouteRegistry.getRoutes().map(this._renderRoute, this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a ReactElement from the specified component and props on behalf of
|
* Create a ReactElement from the specified component and props on behalf of
|
||||||
* the associated Router.
|
* the associated Router.
|
||||||
|
|
|
@ -1,143 +1,24 @@
|
||||||
/* global APP, JitsiMeetJS, loggingConfig */
|
/* global APP, JitsiMeetJS, loggingConfig */
|
||||||
import { isRoomValid } from '../base/conference';
|
|
||||||
import { RouteRegistry } from '../base/navigator';
|
|
||||||
import { Conference } from '../conference';
|
|
||||||
import { WelcomePage } from '../welcome';
|
|
||||||
|
|
||||||
import getTokenData from '../../../modules/tokendata/TokenData';
|
|
||||||
import settings from '../../../modules/settings/Settings';
|
|
||||||
|
|
||||||
import URLProcessor from '../../../modules/config/URLProcessor';
|
import URLProcessor from '../../../modules/config/URLProcessor';
|
||||||
|
import KeyboardShortcut
|
||||||
|
from '../../../modules/keyboardshortcut/keyboardshortcut';
|
||||||
|
import settings from '../../../modules/settings/Settings';
|
||||||
|
import getTokenData from '../../../modules/tokendata/TokenData';
|
||||||
import JitsiMeetLogStorage from '../../../modules/util/JitsiMeetLogStorage';
|
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 Logger = require('jitsi-meet-logger');
|
||||||
const LogCollector = Logger.LogCollector;
|
|
||||||
|
|
||||||
|
export * from './functions.native';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets room name and domain from URL object.
|
* Temporary solution. Later we'll get rid of global APP and set its properties
|
||||||
*
|
* in redux store.
|
||||||
* @param {URL} url - URL object.
|
|
||||||
* @private
|
|
||||||
* @returns {{
|
|
||||||
* domain: (string|undefined),
|
|
||||||
* room: (string|undefined)
|
|
||||||
* }}
|
|
||||||
*/
|
|
||||||
function _getRoomAndDomainFromUrlObject(url) {
|
|
||||||
let domain;
|
|
||||||
let room;
|
|
||||||
|
|
||||||
if (url) {
|
|
||||||
domain = url.hostname;
|
|
||||||
room = url.pathname.substr(1);
|
|
||||||
|
|
||||||
// Convert empty string to undefined to simplify checks.
|
|
||||||
if (room === '') {
|
|
||||||
room = undefined;
|
|
||||||
}
|
|
||||||
if (domain === '') {
|
|
||||||
domain = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
domain,
|
|
||||||
room
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets conference room name and connection domain from URL.
|
|
||||||
*
|
|
||||||
* @param {(string|undefined)} url - URL.
|
|
||||||
* @returns {{
|
|
||||||
* domain: (string|undefined),
|
|
||||||
* room: (string|undefined)
|
|
||||||
* }}
|
|
||||||
*/
|
|
||||||
export function _getRoomAndDomainFromUrlString(url) {
|
|
||||||
// Rewrite the specified URL in order to handle special cases such as
|
|
||||||
// hipchat.com and enso.me which do not follow the common pattern of most
|
|
||||||
// Jitsi Meet deployments.
|
|
||||||
if (typeof url === 'string') {
|
|
||||||
// hipchat.com
|
|
||||||
let regex = /^(https?):\/\/hipchat.com\/video\/call\//gi;
|
|
||||||
let match = regex.exec(url);
|
|
||||||
|
|
||||||
if (!match) {
|
|
||||||
// enso.me
|
|
||||||
regex = /^(https?):\/\/enso\.me\/(?:call|meeting)\//gi;
|
|
||||||
match = regex.exec(url);
|
|
||||||
}
|
|
||||||
if (match && match.length > 1) {
|
|
||||||
/* eslint-disable no-param-reassign, prefer-template */
|
|
||||||
|
|
||||||
url
|
|
||||||
= match[1] /* URL protocol */
|
|
||||||
+ '://enso.hipchat.me/'
|
|
||||||
+ url.substring(regex.lastIndex);
|
|
||||||
|
|
||||||
/* eslint-enable no-param-reassign, prefer-template */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _getRoomAndDomainFromUrlObject(_urlStringToObject(url));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines which route is to be rendered in order to depict a specific Redux
|
|
||||||
* store.
|
|
||||||
*
|
|
||||||
* @param {(Object|Function)} stateOrGetState - Redux state or Regux getState()
|
|
||||||
* method.
|
|
||||||
* @returns {Route}
|
|
||||||
*/
|
|
||||||
export function _getRouteToRender(stateOrGetState) {
|
|
||||||
const state
|
|
||||||
= typeof stateOrGetState === 'function'
|
|
||||||
? stateOrGetState()
|
|
||||||
: stateOrGetState;
|
|
||||||
const room = state['features/base/conference'].room;
|
|
||||||
const component = isRoomValid(room) ? Conference : WelcomePage;
|
|
||||||
|
|
||||||
return RouteRegistry.getRouteByComponent(component);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses a string into a URL (object).
|
|
||||||
*
|
|
||||||
* @param {(string|undefined)} url - The URL to parse.
|
|
||||||
* @private
|
|
||||||
* @returns {URL}
|
|
||||||
*/
|
|
||||||
function _urlStringToObject(url) {
|
|
||||||
let urlObj;
|
|
||||||
|
|
||||||
if (url) {
|
|
||||||
try {
|
|
||||||
urlObj = new URL(url);
|
|
||||||
} catch (ex) {
|
|
||||||
// The return value will signal the failure & the logged
|
|
||||||
// exception will provide the details to the developers.
|
|
||||||
console.log(`${url} seems to be not a valid URL, but it's OK`, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return urlObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Temporary solution. Later we'll get rid of global APP
|
|
||||||
* and set its properties in redux store.
|
|
||||||
*
|
*
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
export function init() {
|
export function init() {
|
||||||
_setConfigParametersFromUrl();
|
URLProcessor.setConfigParametersFromUrl();
|
||||||
_initLogging();
|
_initLogging();
|
||||||
|
|
||||||
APP.keyboardshortcut = KeyboardShortcut;
|
APP.keyboardshortcut = KeyboardShortcut;
|
||||||
|
@ -147,36 +28,14 @@ export function init() {
|
||||||
APP.translation.init(settings.getLanguage());
|
APP.translation.init(settings.getLanguage());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes logging in the app.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
function _initLogging() {
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adjusts the logging levels.
|
* Adjusts the logging levels.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function configureLoggingLevels() {
|
function _configureLoggingLevels() {
|
||||||
// NOTE The library Logger is separated from
|
// NOTE The library Logger is separated from the app loggers, so the levels
|
||||||
// the app loggers, so the levels
|
|
||||||
// have to be set in two places
|
// have to be set in two places
|
||||||
|
|
||||||
// Set default logging level
|
// Set default logging level
|
||||||
|
@ -186,8 +45,8 @@ function configureLoggingLevels() {
|
||||||
Logger.setLogLevel(defaultLogLevel);
|
Logger.setLogLevel(defaultLogLevel);
|
||||||
JitsiMeetJS.setLogLevel(defaultLogLevel);
|
JitsiMeetJS.setLogLevel(defaultLogLevel);
|
||||||
|
|
||||||
// NOTE console was used on purpose here to go around the logging
|
// NOTE console was used on purpose here to go around the logging and always
|
||||||
// and always print the default logging level to the console
|
// print the default logging level to the console
|
||||||
console.info(`Default logging level set to: ${defaultLogLevel}`);
|
console.info(`Default logging level set to: ${defaultLogLevel}`);
|
||||||
|
|
||||||
// Set log level for each logger
|
// Set log level for each logger
|
||||||
|
@ -204,11 +63,22 @@ function configureLoggingLevels() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets config parameters from query string.
|
* Initializes logging in the app.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function _setConfigParametersFromUrl() {
|
function _initLogging() {
|
||||||
URLProcessor.setConfigParametersFromUrl();
|
// 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 Logger.LogCollector(new JitsiMeetLogStorage());
|
||||||
|
Logger.addGlobalTransport(APP.logCollector);
|
||||||
|
JitsiMeetJS.addGlobalLogTransport(APP.logCollector);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
/* global APP, JitsiMeetJS */
|
/* global APP, JitsiMeetJS */
|
||||||
|
|
||||||
import {
|
|
||||||
SET_DOMAIN
|
|
||||||
} from './actionTypes';
|
|
||||||
import './reducer';
|
|
||||||
import UIEvents from '../../../../service/UI/UIEvents';
|
import UIEvents from '../../../../service/UI/UIEvents';
|
||||||
|
|
||||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
import { SET_DOMAIN } from './actionTypes';
|
||||||
const ConferenceEvents = JitsiMeetJS.events.conference;
|
import './reducer';
|
||||||
|
|
||||||
|
const JitsiConferenceEvents = JitsiMeetJS.events.conference;
|
||||||
|
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens new connection.
|
* Opens new connection.
|
||||||
|
@ -42,7 +40,7 @@ export function connect() {
|
||||||
// room. It will then restart the media session when someone
|
// room. It will then restart the media session when someone
|
||||||
// eventually join the room which will start the stats again.
|
// eventually join the room which will start the stats again.
|
||||||
APP.conference.addConferenceListener(
|
APP.conference.addConferenceListener(
|
||||||
ConferenceEvents.BEFORE_STATISTICS_DISPOSED,
|
JitsiConferenceEvents.BEFORE_STATISTICS_DISPOSED,
|
||||||
() => {
|
() => {
|
||||||
if (APP.logCollector) {
|
if (APP.logCollector) {
|
||||||
APP.logCollector.flush();
|
APP.logCollector.flush();
|
||||||
|
@ -74,8 +72,8 @@ export function connect() {
|
||||||
* @returns {Function}
|
* @returns {Function}
|
||||||
*/
|
*/
|
||||||
export function disconnect() {
|
export function disconnect() {
|
||||||
// XXX For web based version we use conference
|
// XXX For web based version we use conference hanging up logic from the old
|
||||||
// hanging up logic from the old app.
|
// app.
|
||||||
return () => APP.conference.hangup();
|
return () => APP.conference.hangup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import JitsiMeetJS from './';
|
import JitsiMeetJS from './';
|
||||||
import {
|
import {
|
||||||
LIB_DISPOSED,
|
LIB_DISPOSED,
|
||||||
|
@ -42,9 +40,9 @@ export function initLib() {
|
||||||
throw new Error('Cannot initialize lib-jitsi-meet without config');
|
throw new Error('Cannot initialize lib-jitsi-meet without config');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!React.View) {
|
|
||||||
// XXX Temporarily until conference.js is moved to the React app we
|
// XXX Temporarily until conference.js is moved to the React app we
|
||||||
// shouldn't use JitsiMeetJS from the React app.
|
// shouldn't use JitsiMeetJS from the React app.
|
||||||
|
if (typeof APP !== 'undefined') {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { loadScript } from '../../base/util';
|
import { loadScript } from '../../base/util';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,10 +8,10 @@ import { loadScript } from '../../base/util';
|
||||||
* @returns {Promise<Object>}
|
* @returns {Promise<Object>}
|
||||||
*/
|
*/
|
||||||
export function loadConfig(host, path = '/config.js') {
|
export function loadConfig(host, path = '/config.js') {
|
||||||
if (!React.View) {
|
// Returns config.js file from global scope. We can't use the version that's
|
||||||
// Returns config.js file from global scope. We can't use the version
|
// being used for the React Native app because the old/current Web app uses
|
||||||
// that's being used for the React Native app because the old/current
|
// config from the global scope.
|
||||||
// Web app uses config from the global scope.
|
if (typeof APP !== 'undefined') {
|
||||||
return Promise.resolve(window.config);
|
return Promise.resolve(window.config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
/* global APP, config */
|
|
||||||
import ConferenceUrl from '../../../modules/URL/ConferenceUrl';
|
|
||||||
import BoshAddressChoice from '../../../modules/config/BoshAddressChoice';
|
|
||||||
import { obtainConfig, setTokenData } from './functions';
|
|
||||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If we have an HTTP endpoint for getting config.json configured
|
|
||||||
* we're going to read it and override properties from config.js and
|
|
||||||
* interfaceConfig.js. If there is no endpoint we'll just
|
|
||||||
* continue with initialization.
|
|
||||||
* Keep in mind that if the endpoint has been configured and we fail
|
|
||||||
* to obtain the config for any reason then the conference won't
|
|
||||||
* start and error message will be displayed to the user.
|
|
||||||
*
|
|
||||||
* @returns {Function}
|
|
||||||
*/
|
|
||||||
export function obtainConfigAndInit() {
|
|
||||||
return () => {
|
|
||||||
const room = APP.conference.roomName;
|
|
||||||
|
|
||||||
if (config.configLocation) {
|
|
||||||
const location = config.configLocation;
|
|
||||||
|
|
||||||
obtainConfig(location, room)
|
|
||||||
.then(_obtainConfigHandler)
|
|
||||||
.then(_initConference)
|
|
||||||
.catch(err => {
|
|
||||||
// Show obtain config error,
|
|
||||||
// pass the error object for report
|
|
||||||
APP.UI.messageHandler.openReportDialog(
|
|
||||||
null, 'dialog.connectError', err);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
BoshAddressChoice.chooseAddress(config, room);
|
|
||||||
_initConference();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain config handler.
|
|
||||||
*
|
|
||||||
* @returns {Promise}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
function _obtainConfigHandler() {
|
|
||||||
const now = window.performance.now();
|
|
||||||
|
|
||||||
APP.connectionTimes['configuration.fetched'] = now;
|
|
||||||
logger.log('(TIME) configuration fetched:\t', now);
|
|
||||||
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialization of the app.
|
|
||||||
*
|
|
||||||
* @returns {void}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
function _initConference() {
|
|
||||||
setTokenData();
|
|
||||||
|
|
||||||
// Initialize the conference URL handler
|
|
||||||
APP.ConferenceUrl = new ConferenceUrl(window.location);
|
|
||||||
}
|
|
|
@ -1,11 +1,9 @@
|
||||||
/* global $, APP, interfaceConfig */
|
/* global $, APP, interfaceConfig */
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { connect as reactReduxConnect } from 'react-redux';
|
import { connect as reactReduxConnect } from 'react-redux';
|
||||||
|
|
||||||
import {
|
import { connect, disconnect } from '../../base/connection';
|
||||||
connect,
|
|
||||||
disconnect
|
|
||||||
} from '../../base/connection';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For legacy reasons, inline style for display none.
|
* For legacy reasons, inline style for display none.
|
||||||
|
@ -19,6 +17,16 @@ const DISPLAY_NONE_STYLE = {
|
||||||
* Implements a React Component which renders initial conference layout
|
* Implements a React Component which renders initial conference layout
|
||||||
*/
|
*/
|
||||||
class Conference extends Component {
|
class Conference extends Component {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conference component's property types.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
*/
|
||||||
|
static propTypes = {
|
||||||
|
dispatch: React.PropTypes.func
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Until we don't rewrite UI using react components
|
* Until we don't rewrite UI using react components
|
||||||
* we use UI.start from old app. Also method translates
|
* we use UI.start from old app. Also method translates
|
||||||
|
@ -45,15 +53,6 @@ class Conference extends Component {
|
||||||
this.props.dispatch(disconnect());
|
this.props.dispatch(disconnect());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Conference component's property types.
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
*/
|
|
||||||
static propTypes = {
|
|
||||||
dispatch: React.PropTypes.func
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes Conference component instance.
|
* Initializes Conference component instance.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,108 +0,0 @@
|
||||||
/* global APP, config */
|
|
||||||
import HttpConfigFetch from '../../../modules/config/HttpConfigFetch';
|
|
||||||
import ConferenceUrl from '../../../modules/URL/ConferenceUrl';
|
|
||||||
import BoshAddressChoice from '../../../modules/config/BoshAddressChoice';
|
|
||||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If we have an HTTP endpoint for getting config.json configured
|
|
||||||
* we're going to read it and override properties from config.js and
|
|
||||||
* interfaceConfig.js. If there is no endpoint we'll just
|
|
||||||
* continue with initialization.
|
|
||||||
* Keep in mind that if the endpoint has been configured and we fail
|
|
||||||
* to obtain the config for any reason then the conference won't
|
|
||||||
* start and error message will be displayed to the user.
|
|
||||||
*
|
|
||||||
* @returns {Function}
|
|
||||||
*/
|
|
||||||
export function obtainConfigAndInit() {
|
|
||||||
// Skip initialization if conference is already initialized
|
|
||||||
if (!APP.ConferenceUrl) {
|
|
||||||
const room = APP.conference.roomName;
|
|
||||||
|
|
||||||
if (config.configLocation) {
|
|
||||||
const location = config.configLocation;
|
|
||||||
|
|
||||||
obtainConfig(location, room)
|
|
||||||
.then(_obtainConfigHandler)
|
|
||||||
.then(_initConference)
|
|
||||||
.catch(err => {
|
|
||||||
// Show obtain config error,
|
|
||||||
// pass the error object for report
|
|
||||||
APP.UI.messageHandler.openReportDialog(
|
|
||||||
null, 'dialog.connectError', err);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
BoshAddressChoice.chooseAddress(config, room);
|
|
||||||
_initConference();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain config handler.
|
|
||||||
*
|
|
||||||
* @returns {Promise}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
function _obtainConfigHandler() {
|
|
||||||
const now = window.performance.now();
|
|
||||||
|
|
||||||
APP.connectionTimes['configuration.fetched'] = now;
|
|
||||||
logger.log('(TIME) configuration fetched:\t', now);
|
|
||||||
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialization of the app.
|
|
||||||
*
|
|
||||||
* @returns {void}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
function _initConference() {
|
|
||||||
setTokenData();
|
|
||||||
|
|
||||||
// Initialize the conference URL handler
|
|
||||||
APP.ConferenceUrl = new ConferenceUrl(window.location);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Promise wrapper on obtain config method.
|
|
||||||
* When HttpConfigFetch will be moved to React app
|
|
||||||
* it's better to use load config instead.
|
|
||||||
*
|
|
||||||
* @param {string} location - URL of the domain.
|
|
||||||
* @param {string} room - Room name.
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
export function obtainConfig(location, room) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
HttpConfigFetch.obtainConfig(location, room, (success, error) => {
|
|
||||||
if (success) {
|
|
||||||
resolve();
|
|
||||||
} else {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If JWT token data it will be used for local user settings.
|
|
||||||
*
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
export function setTokenData() {
|
|
||||||
const localUser = APP.tokenData.caller;
|
|
||||||
|
|
||||||
if (localUser) {
|
|
||||||
const email = localUser.getEmail();
|
|
||||||
const avatarUrl = localUser.getAvatarUrl();
|
|
||||||
const name = localUser.getName();
|
|
||||||
|
|
||||||
APP.settings.setEmail((email || '').trim(), true);
|
|
||||||
APP.settings.setAvatarUrl((avatarUrl || '').trim());
|
|
||||||
APP.settings.setDisplayName((name || '').trim(), true);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,14 @@
|
||||||
|
/* global APP, config */
|
||||||
|
|
||||||
|
import BoshAddressChoice from '../../../modules/config/BoshAddressChoice';
|
||||||
|
import HttpConfigFetch from '../../../modules/config/HttpConfigFetch';
|
||||||
|
import ConferenceUrl from '../../../modules/URL/ConferenceUrl';
|
||||||
|
|
||||||
import { RouteRegistry } from '../base/navigator';
|
import { RouteRegistry } from '../base/navigator';
|
||||||
|
|
||||||
import { Conference } from './components';
|
import { Conference } from './components';
|
||||||
import { obtainConfigAndInit } from './functions';
|
|
||||||
|
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register route for Conference (page).
|
* Register route for Conference (page).
|
||||||
|
@ -9,9 +16,111 @@ import { obtainConfigAndInit } from './functions';
|
||||||
RouteRegistry.register({
|
RouteRegistry.register({
|
||||||
component: Conference,
|
component: Conference,
|
||||||
onEnter: () => {
|
onEnter: () => {
|
||||||
// XXX: If config or jwt are set by hash or query parameters
|
// XXX If config or jwt are set by hash or query parameters
|
||||||
// Getting raw URL before stripping it.
|
// Getting raw URL before stripping it.
|
||||||
obtainConfigAndInit();
|
_obtainConfigAndInit();
|
||||||
},
|
},
|
||||||
path: '/:room'
|
path: '/:room'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialization of the app.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function _initConference() {
|
||||||
|
_setTokenData();
|
||||||
|
|
||||||
|
// Initialize the conference URL handler
|
||||||
|
APP.ConferenceUrl = new ConferenceUrl(window.location);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Promise wrapper on obtain config method. When HttpConfigFetch will be moved
|
||||||
|
* to React app it's better to use load config instead.
|
||||||
|
*
|
||||||
|
* @param {string} location - URL of the domain.
|
||||||
|
* @param {string} room - Room name.
|
||||||
|
* @private
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function _obtainConfig(location, room) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
HttpConfigFetch.obtainConfig(location, room, (success, error) => {
|
||||||
|
if (success) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we have an HTTP endpoint for getting config.json configured we're going to
|
||||||
|
* read it and override properties from config.js and interfaceConfig.js. If
|
||||||
|
* there is no endpoint we'll just continue with initialization. Keep in mind
|
||||||
|
* that if the endpoint has been configured and we fail to obtain the config for
|
||||||
|
* any reason then the conference won't start and error message will be
|
||||||
|
* displayed to the user.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function _obtainConfigAndInit() {
|
||||||
|
// Skip initialization if conference is initialized already.
|
||||||
|
if (typeof APP !== 'undefined' && !APP.ConferenceUrl) {
|
||||||
|
const location = config.configLocation;
|
||||||
|
const room = APP.conference.roomName;
|
||||||
|
|
||||||
|
if (location) {
|
||||||
|
_obtainConfig(location, room)
|
||||||
|
.then(() => {
|
||||||
|
_obtainConfigHandler();
|
||||||
|
_initConference();
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
// Show obtain config error.
|
||||||
|
APP.UI.messageHandler.openReportDialog(
|
||||||
|
null, 'dialog.connectError', err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
BoshAddressChoice.chooseAddress(config, room);
|
||||||
|
_initConference();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain config handler.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
function _obtainConfigHandler() {
|
||||||
|
const now = window.performance.now();
|
||||||
|
|
||||||
|
APP.connectionTimes['configuration.fetched'] = now;
|
||||||
|
logger.log('(TIME) configuration fetched:\t', now);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If JWT token data it will be used for local user settings.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function _setTokenData() {
|
||||||
|
const localUser = APP.tokenData.caller;
|
||||||
|
|
||||||
|
if (localUser) {
|
||||||
|
const email = localUser.getEmail();
|
||||||
|
const avatarUrl = localUser.getAvatarUrl();
|
||||||
|
const name = localUser.getName();
|
||||||
|
|
||||||
|
APP.settings.setEmail((email || '').trim(), true);
|
||||||
|
APP.settings.setAvatarUrl((avatarUrl || '').trim());
|
||||||
|
APP.settings.setDisplayName((name || '').trim(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,26 +1,10 @@
|
||||||
/* global APP */
|
/* global APP */
|
||||||
|
|
||||||
import { RouteRegistry } from '../base/navigator';
|
import { RouteRegistry } from '../base/navigator';
|
||||||
import { generateRoomWithoutSeparator } from '../base/util';
|
import { generateRoomWithoutSeparator } from '../base/util';
|
||||||
|
|
||||||
import { WelcomePage } from './components';
|
import { WelcomePage } from './components';
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function that checks if welcome page is enabled and if it isn't
|
|
||||||
* redirects to randomly created conference.
|
|
||||||
*
|
|
||||||
* @param {Object} nextState - Next router state.
|
|
||||||
* @param {Function} replace - Function to redirect to another path.
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
function onEnter(nextState, replace) {
|
|
||||||
if (!APP.settings.isWelcomePageEnabled()) {
|
|
||||||
const generatedRoomname = generateRoomWithoutSeparator();
|
|
||||||
const normalizedRoomname = generatedRoomname.toLowerCase();
|
|
||||||
|
|
||||||
replace(`/${normalizedRoomname}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register route for WelcomePage.
|
* Register route for WelcomePage.
|
||||||
*/
|
*/
|
||||||
|
@ -29,3 +13,20 @@ RouteRegistry.register({
|
||||||
onEnter,
|
onEnter,
|
||||||
path: '/'
|
path: '/'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the Welcome page/screen is disabled, generates a (random) room (name) so
|
||||||
|
* that the Welcome page/screen is skipped and the Conference page/screen is
|
||||||
|
* presented instead.
|
||||||
|
*
|
||||||
|
* @param {Object} nextState - The next Router state.
|
||||||
|
* @param {Function} replace - The function to redirect to another path.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
function onEnter(nextState, replace) {
|
||||||
|
if (typeof APP !== 'undefined' && !APP.settings.isWelcomePageEnabled()) {
|
||||||
|
const room = generateRoomWithoutSeparator();
|
||||||
|
|
||||||
|
replace(`/${room}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -61,7 +61,9 @@ class Root extends Component {
|
||||||
|
|
||||||
// XXX Start with an empty URL if getting the initial URL fails;
|
// XXX Start with an empty URL if getting the initial URL fails;
|
||||||
// otherwise, nothing will be rendered.
|
// otherwise, nothing will be rendered.
|
||||||
|
if (this.state.url !== null) {
|
||||||
this.setState({ url: null });
|
this.setState({ url: null });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,15 @@
|
||||||
/* global APP */
|
/* global APP */
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import { browserHistory } from 'react-router';
|
import { browserHistory } from 'react-router';
|
||||||
import {
|
import { routerMiddleware, routerReducer } from 'react-router-redux';
|
||||||
routerMiddleware,
|
|
||||||
routerReducer
|
|
||||||
} from 'react-router-redux';
|
|
||||||
import { compose, createStore } from 'redux';
|
import { compose, createStore } from 'redux';
|
||||||
import Thunk from 'redux-thunk';
|
import Thunk from 'redux-thunk';
|
||||||
|
|
||||||
import config from './config';
|
import config from './config';
|
||||||
import { App } from './features/app';
|
import { App } from './features/app';
|
||||||
import {
|
import { MiddlewareRegistry, ReducerRegistry } from './features/base/redux';
|
||||||
MiddlewareRegistry,
|
|
||||||
ReducerRegistry
|
|
||||||
} from './features/base/redux';
|
|
||||||
|
|
||||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
||||||
|
|
||||||
|
@ -49,7 +44,7 @@ if (typeof window === 'object'
|
||||||
const store = createStore(reducer, middleware);
|
const store = createStore(reducer, middleware);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the app when DOM tree has been loaded.
|
* Renders the app when the DOM tree has been loaded.
|
||||||
*/
|
*/
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
const now = window.performance.now();
|
const now = window.performance.now();
|
||||||
|
@ -67,8 +62,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop collecting the logs and disposing the API when
|
* Stops collecting the logs and disposing the API when the user closes the
|
||||||
* user closes the page.
|
* page.
|
||||||
*/
|
*/
|
||||||
window.addEventListener('beforeunload', () => {
|
window.addEventListener('beforeunload', () => {
|
||||||
// Stop the LogCollector
|
// Stop the LogCollector
|
||||||
|
|
Loading…
Reference in New Issue