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