diff --git a/conference.js b/conference.js index 8a91e98749..314ae3d24b 100644 --- a/conference.js +++ b/conference.js @@ -2320,13 +2320,14 @@ export default { * @private */ _initDeviceList() { - if (JitsiMeetJS.mediaDevices.isDeviceListAvailable() - && JitsiMeetJS.mediaDevices.isDeviceChangeAvailable()) { - JitsiMeetJS.mediaDevices.enumerateDevices(devices => { - // Ugly way to synchronize real device IDs with local - // storage and settings menu. This is a workaround until - // getConstraints() method will be implemented - // in browsers. + const { mediaDevices } = JitsiMeetJS; + + if (mediaDevices.isDeviceListAvailable() + && mediaDevices.isDeviceChangeAvailable()) { + mediaDevices.enumerateDevices(devices => { + // Ugly way to synchronize real device IDs with local storage + // and settings menu. This is a workaround until + // getConstraints() method will be implemented in browsers. const { dispatch } = APP.store; if (this.localAudio) { @@ -2334,7 +2335,6 @@ export default { micDeviceId: this.localAudio.getDeviceId() })); } - if (this.localVideo) { dispatch(updateSettings({ cameraDeviceId: this.localVideo.getDeviceId() @@ -2347,9 +2347,8 @@ export default { }); this.deviceChangeListener = devices => - window.setTimeout( - () => this._onDeviceListChanged(devices), 0); - JitsiMeetJS.mediaDevices.addEventListener( + window.setTimeout(() => this._onDeviceListChanged(devices), 0); + mediaDevices.addEventListener( JitsiMediaDevicesEvents.DEVICE_LIST_CHANGED, this.deviceChangeListener); } diff --git a/react/features/app/actions.js b/react/features/app/actions.js index cd3e75615f..4e5736393f 100644 --- a/react/features/app/actions.js +++ b/react/features/app/actions.js @@ -78,10 +78,10 @@ function _appNavigateToMandatoryLocation( */ function loadConfigSettled(error, config) { // Due to the asynchronous nature of the loading, the specified config - // may or may not be required by the time the notification arrives. - // If we receive the config for a location we are no longer interested - // in, "ignore" it - deliver it to the external API, for example, but do - // not proceed with the appNavigate procedure/process. + // may or may not be required by the time the notification arrives. If + // we receive the config for a location we are no longer interested in, + // "ignore" it - deliver it to the external API, for example, but do not + // proceed with the appNavigate procedure/process. if (getState()['features/base/config'].locationURL === locationURL) { dispatch(setLocationURL(locationURL)); dispatch(setConfig(config)); @@ -90,8 +90,8 @@ function _appNavigateToMandatoryLocation( error || (error = new Error('Config no longer needed!')); // XXX The failure could be, for example, because of a - // certificate-related error. In which case the connection will - // fail later in Strophe anyway. + // certificate-related error. In which case the connection will fail + // later in Strophe anyway. dispatch(loadConfigError(error, locationURL)); throw error; diff --git a/react/features/app/components/AbstractApp.js b/react/features/app/components/AbstractApp.js index 1893b4f0b9..7bb48ece7c 100644 --- a/react/features/app/components/AbstractApp.js +++ b/react/features/app/components/AbstractApp.js @@ -23,8 +23,8 @@ import { OverlayContainer } from '../../overlay'; import { appNavigate, appWillMount, appWillUnmount } from '../actions'; /** - * The default URL to open if no other was specified to {@code AbstractApp} - * via props. + * The default URL to open if no other was specified to {@code AbstractApp} via + * props. * * FIXME: This is not at the best place here. This should be either in the * base/settings feature or a default in base/config. @@ -78,6 +78,12 @@ export class AbstractApp extends Component { this.state = { + /** + * The state of the »possible« async initialization of + * the {@code AbstractApp}. + */ + appAsyncInitialized: false, + /** * The Route rendered by this {@code AbstractApp}. * @@ -85,12 +91,6 @@ export class AbstractApp extends Component { */ route: {}, - /** - * The state of the »possible« async initialization of - * the {@code AbstractApp}. - */ - appAsyncInitialized: false, - /** * The redux store used by this {@code AbstractApp}. * @@ -239,8 +239,7 @@ export class AbstractApp extends Component { * @returns {ReactElement} */ render() { - const { appAsyncInitialized, route } = this.state; - const { component } = route; + const { appAsyncInitialized, route: { component } } = this.state; if (appAsyncInitialized && component) { return ( @@ -357,7 +356,7 @@ export class AbstractApp extends Component { return ( this.props.defaultURL || this._getStore().getState()['features/base/settings'] - .serverURL + .serverURL || DEFAULT_URL); } @@ -435,9 +434,7 @@ export class AbstractApp extends Component { // performed before setState completes, the app may not navigate to the // expected route. In order to mitigate the problem, _navigate was // changed to return a Promise. - return new Promise(resolve => { - this.setState({ route }, resolve); - }); + return new Promise(resolve => this.setState({ route }, resolve)); } /** diff --git a/react/features/app/functions.native.js b/react/features/app/functions.native.js index 5387f67a49..6b0e8033e7 100644 --- a/react/features/app/functions.native.js +++ b/react/features/app/functions.native.js @@ -3,7 +3,6 @@ import { NativeModules } from 'react-native'; export * from './functions.any'; -export * from './router'; /** * Returns application name. diff --git a/react/features/app/functions.web.js b/react/features/app/functions.web.js index 5daf84694a..c2006d46bf 100644 --- a/react/features/app/functions.web.js +++ b/react/features/app/functions.web.js @@ -1,7 +1,6 @@ // @flow export * from './functions.any'; -export * from './router'; declare var interfaceConfig: Object; diff --git a/react/features/app/router.js b/react/features/app/getRouteToRender.js similarity index 86% rename from react/features/app/router.js rename to react/features/app/getRouteToRender.js index 52e7415ebf..2287f2217e 100644 --- a/react/features/app/router.js +++ b/react/features/app/getRouteToRender.js @@ -1,4 +1,5 @@ // @flow + import type { Component } from 'react'; import { isRoomValid } from '../base/conference'; @@ -35,11 +36,11 @@ export type Route = { * Determines which route is to be rendered in order to depict a specific Redux * store. * - * @param {(Object|Function)} stateful - Redux state or Regux getState() - * method. + * @param {(Function|Object)} stateful - THe redux store, state, or + * {@code getState} function. * @returns {Promise} */ -export function getRouteToRender(stateful: Object | Function): Promise { +export function _getRouteToRender(stateful: Function | Object): Promise { const state = toState(stateful); const { room } = state['features/base/conference']; const isMobileApp = navigator.product === 'ReactNative'; @@ -51,11 +52,11 @@ export function getRouteToRender(stateful: Object | Function): Promise { }; return new Promise(resolve => { - // First check if the current endpoint supports WebRTC. We are + // First, check if the current endpoint supports WebRTC. We are // intentionally not performing the check for mobile browsers because: - // - the welcome page is mobile ready - // - if the URL points to a conference, getDeepLinkingPage will take - // care of it + // - the WelcomePage is mobile ready; + // - if the URL points to a conference, getDeepLinkingPage will take + // care of it. if (!isMobileBrowser && !JitsiMeetJS.isWebRtcSupported()) { route.component = UnsupportedDesktopBrowser; resolve(route); @@ -70,8 +71,8 @@ export function getRouteToRender(stateful: Object | Function): Promise { } else { // Update the location if it doesn't match. This happens when a // room is joined from the welcome page. The reason for doing - // this instead of using the history API is that we want to - // load the config.js which takes the room into account. + // this instead of using the history API is that we want to load + // the config.js which takes the room into account. const { locationURL } = state['features/base/connection']; // eslint-disable-next-line no-negated-condition @@ -91,8 +92,8 @@ export function getRouteToRender(stateful: Object | Function): Promise { } if (!isWelcomePageUserEnabled(state)) { - // Web: if the welcome page is disabled, go directly to a - // random room. + // Web: if the welcome page is disabled, go directly to a random + // room. let href = window.location.href; diff --git a/react/features/app/middleware.js b/react/features/app/middleware.js index faf3ae7e9e..452df63525 100644 --- a/react/features/app/middleware.js +++ b/react/features/app/middleware.js @@ -7,7 +7,7 @@ import { } from '../base/connection'; import { MiddlewareRegistry } from '../base/redux'; -import { getRouteToRender } from './router'; +import { _getRouteToRender } from './getRouteToRender'; MiddlewareRegistry.register(store => next => action => { switch (action.type) { @@ -74,7 +74,7 @@ function _navigate({ getState }) { const state = getState(); const { app } = state['features/app']; - getRouteToRender(state).then(route => app._navigate(route)); + _getRouteToRender(state).then(route => app._navigate(route)); } /** diff --git a/react/features/base/config/functions.js b/react/features/base/config/functions.js index e73e622d87..58ca66efa6 100644 --- a/react/features/base/config/functions.js +++ b/react/features/base/config/functions.js @@ -149,6 +149,24 @@ const logger = require('jitsi-meet-logger').getLogger(__filename); export { default as getRoomName } from './getRoomName'; export { parseURLParams }; +/** + * 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 from which the config is to be + * obtained. + * @param {string} room - Room name. + * @private + * @returns {Promise} + */ +export function obtainConfig(location: string, room: string): Promise { + return new Promise((resolve, reject) => + _obtainConfig(location, room, (success, error) => { + success ? resolve() : reject(error); + }) + ); +} + /** * Sends HTTP POST request to specified {@code endpoint}. In request the name * of the room is included in JSON format: @@ -163,10 +181,7 @@ export { parseURLParams }; * @param {Function} complete - The callback to invoke upon success or failure. * @returns {void} */ -export function obtainConfig( - endpoint: string, - roomName: string, - complete: Function) { +function _obtainConfig(endpoint: string, roomName: string, complete: Function) { logger.info(`Send config request to ${endpoint} for room: ${roomName}`); $.ajax( endpoint, diff --git a/react/features/base/connection/actions.web.js b/react/features/base/connection/actions.web.js index 5ee29aafb6..35c9792029 100644 --- a/react/features/base/connection/actions.web.js +++ b/react/features/base/connection/actions.web.js @@ -20,10 +20,8 @@ export { */ export function connect() { return (dispatch: Dispatch<*>, getState: Function) => { - const state = getState(); - // XXX Lib-jitsi-meet does not accept uppercase letters. - const room = state['features/base/conference'].room.toLowerCase(); + const room = getState()['features/base/conference'].room.toLowerCase(); // XXX For web based version we use conference initialization logic // from the old app (at the moment of writing). diff --git a/react/features/conference/components/Conference.native.js b/react/features/conference/components/Conference.native.js index a4954f11a8..8382f7ed92 100644 --- a/react/features/conference/components/Conference.native.js +++ b/react/features/conference/components/Conference.native.js @@ -184,8 +184,6 @@ class Conference extends Component { componentWillReceiveProps(nextProps: Props) { const { _locationURL: oldLocationURL, - _onConnect, - _onDisconnect, _participantCount: oldParticipantCount, _room: oldRoom, _setToolboxVisible @@ -197,10 +195,10 @@ class Conference extends Component { } = nextProps; // If the location URL changes we need to reconnect. - oldLocationURL !== newLocationURL && _onDisconnect(); + oldLocationURL !== newLocationURL && this.props._onDisconnect(); // Start the connection process when there is a (valid) room. - oldRoom !== newRoom && newRoom && _onConnect(); + oldRoom !== newRoom && newRoom && this.props._onConnect(); if (oldParticipantCount === 1) { newParticipantCount > 1 && _setToolboxVisible(false); @@ -342,9 +340,7 @@ class Conference extends Component { * @returns {React$Node} */ _renderConferenceNotification() { - return ConferenceNotification - ? - : undefined; + return ConferenceNotification ? : undefined; } } @@ -356,6 +352,7 @@ class Conference extends Component { * @returns {{ * _onConnect: Function, * _onDisconnect: Function, + * _onHardwareBackPress: Function, * _setToolboxVisible: Function * }} */ diff --git a/react/features/conference/components/Conference.web.js b/react/features/conference/components/Conference.web.js index 6edaf432a6..4a3d17dfe6 100644 --- a/react/features/conference/components/Conference.web.js +++ b/react/features/conference/components/Conference.web.js @@ -28,24 +28,6 @@ declare var interfaceConfig: Object; const logger = require('jitsi-meet-logger').getLogger(__filename); -/** - * 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 from which the config is to be - * obtained. - * @param {string} room - Room name. - * @private - * @returns {Promise} - */ -function _obtainConfig(location: string, room: string) { - return new Promise((resolve, reject) => - obtainConfig(location, room, (success, error) => { - success ? resolve() : reject(error); - }) - ); -} - /** * DOM events for when full screen mode has changed. Different browsers need * different vendor prefixes. @@ -119,7 +101,7 @@ class Conference extends Component { const { configLocation } = config; if (configLocation) { - _obtainConfig(configLocation, this.props._room) + obtainConfig(configLocation, this.props._room) .then(() => { const now = window.performance.now(); @@ -133,8 +115,8 @@ class Conference extends Component { // Show obtain config error. APP.UI.messageHandler.showError({ - titleKey: 'connection.CONNFAIL', - descriptionKey: 'dialog.connectError' + descriptionKey: 'dialog.connectError', + titleKey: 'connection.CONNFAIL' }); }); } else { @@ -253,7 +235,8 @@ class Conference extends Component { * @param {Object} state - The Redux state. * @private * @returns {{ - * _iAmRecorder: boolean + * _iAmRecorder: boolean, + * _room: ?string * }} */ function _mapStateToProps(state) { diff --git a/react/features/welcome/components/BlankPage.native.js b/react/features/welcome/components/BlankPage.native.js index 2c3b0f04fb..60c5e9a0ef 100644 --- a/react/features/welcome/components/BlankPage.native.js +++ b/react/features/welcome/components/BlankPage.native.js @@ -10,11 +10,11 @@ import { NetworkActivityIndicator } from '../../mobile/network-activity'; import LocalVideoTrackUnderlay from './LocalVideoTrackUnderlay'; /** - * {@code BlankPage} React {@code Component}'s prop types. + * The type of React {@code Component} props of {@link BlankPage}. */ type Props = { dispatch: Dispatch<*> -} +}; /** * The React {@code Component} displayed by {@code AbstractApp} when it has no