core: refactor routing (continued)
This commit is contained in:
parent
155e02bbfb
commit
c203215c54
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
import { NativeModules } from 'react-native';
|
||||
|
||||
export * from './functions.any';
|
||||
export * from './router';
|
||||
|
||||
/**
|
||||
* Returns application name.
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// @flow
|
||||
|
||||
export * from './functions.any';
|
||||
export * from './router';
|
||||
|
||||
declare var interfaceConfig: Object;
|
||||
|
||||
|
|
|
@ -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<Route>}
|
||||
*/
|
||||
export function getRouteToRender(stateful: Object | Function): Promise<Route> {
|
||||
export function _getRouteToRender(stateful: Function | Object): Promise<Route> {
|
||||
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<Route> {
|
|||
};
|
||||
|
||||
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<Route> {
|
|||
} 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<Route> {
|
|||
}
|
||||
|
||||
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;
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<void>}
|
||||
*/
|
||||
export function obtainConfig(location: string, room: string): Promise<void> {
|
||||
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,
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -184,8 +184,6 @@ class Conference extends Component<Props> {
|
|||
componentWillReceiveProps(nextProps: Props) {
|
||||
const {
|
||||
_locationURL: oldLocationURL,
|
||||
_onConnect,
|
||||
_onDisconnect,
|
||||
_participantCount: oldParticipantCount,
|
||||
_room: oldRoom,
|
||||
_setToolboxVisible
|
||||
|
@ -197,10 +195,10 @@ class Conference extends Component<Props> {
|
|||
} = 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<Props> {
|
|||
* @returns {React$Node}
|
||||
*/
|
||||
_renderConferenceNotification() {
|
||||
return ConferenceNotification
|
||||
? <ConferenceNotification />
|
||||
: undefined;
|
||||
return ConferenceNotification ? <ConferenceNotification /> : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,6 +352,7 @@ class Conference extends Component<Props> {
|
|||
* @returns {{
|
||||
* _onConnect: Function,
|
||||
* _onDisconnect: Function,
|
||||
* _onHardwareBackPress: Function,
|
||||
* _setToolboxVisible: Function
|
||||
* }}
|
||||
*/
|
||||
|
|
|
@ -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<Props> {
|
|||
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<Props> {
|
|||
|
||||
// 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<Props> {
|
|||
* @param {Object} state - The Redux state.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _iAmRecorder: boolean
|
||||
* _iAmRecorder: boolean,
|
||||
* _room: ?string
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue