Clean up routing logic
This commit is contained in:
parent
62bafcaf63
commit
57ba702dda
|
@ -1,16 +1,24 @@
|
||||||
import { setRoom } from '../base/conference';
|
import { setRoom } from '../base/conference';
|
||||||
import { getDomain, setDomain } from '../base/connection';
|
import { getDomain, setDomain } from '../base/connection';
|
||||||
import { loadConfig, setConfig } from '../base/lib-jitsi-meet';
|
import { loadConfig, setConfig } from '../base/lib-jitsi-meet';
|
||||||
import { Platform } from '../base/react';
|
|
||||||
|
|
||||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
|
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
|
||||||
import {
|
import {
|
||||||
_getRoomAndDomainFromUrlString,
|
_getRoomAndDomainFromUrlString,
|
||||||
_getRouteToRender,
|
_getRouteToRender,
|
||||||
|
areRoutesEqual,
|
||||||
init
|
init
|
||||||
} from './functions';
|
} from './functions';
|
||||||
import './reducer';
|
import './reducer';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variable saving current route of the app. Later it will be extracted as
|
||||||
|
* a property of the class with Router specific logic.
|
||||||
|
*
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
let currentRoute = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Temporary solution. Should dispatch actions related to initial settings of
|
* Temporary solution. Should dispatch actions related to initial settings of
|
||||||
* the app like setting log levels, reading the config parameters from query
|
* the app like setting log levels, reading the config parameters from query
|
||||||
|
@ -42,9 +50,7 @@ export function appNavigate(urlOrRoom) {
|
||||||
// current conference and start a new one with the new room name or
|
// current conference and start a new one with the new room name or
|
||||||
// domain.
|
// domain.
|
||||||
|
|
||||||
if (room === 'mobile-app') {
|
if (typeof domain === 'undefined' || oldDomain === domain) {
|
||||||
return;
|
|
||||||
} else if (typeof domain === 'undefined' || oldDomain === domain) {
|
|
||||||
// If both domain and room vars became undefined, that means we're
|
// If both domain and room vars became undefined, that means we're
|
||||||
// actually dealing with just room name and not with URL.
|
// actually dealing with just room name and not with URL.
|
||||||
dispatch(
|
dispatch(
|
||||||
|
@ -63,7 +69,15 @@ export function appNavigate(urlOrRoom) {
|
||||||
loadConfig(`https://${domain}`)
|
loadConfig(`https://${domain}`)
|
||||||
.then(
|
.then(
|
||||||
config => configLoaded(/* err */ undefined, config),
|
config => configLoaded(/* err */ undefined, config),
|
||||||
err => configLoaded(err, /* config */ undefined));
|
err => configLoaded(err, /* config */ undefined))
|
||||||
|
.then(() => {
|
||||||
|
const link = typeof room === 'undefined'
|
||||||
|
&& typeof domain === 'undefined'
|
||||||
|
? urlOrRoom
|
||||||
|
: room;
|
||||||
|
|
||||||
|
dispatch(_setRoomAndNavigate(link));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,9 +101,6 @@ export function appNavigate(urlOrRoom) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We set room name only here to prevent race conditions on app
|
|
||||||
// start to not make app re-render conference page for two times.
|
|
||||||
dispatch(setRoom(room));
|
|
||||||
dispatch(setConfig(config));
|
dispatch(setConfig(config));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -127,20 +138,6 @@ export function appWillUnmount(app) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Navigates to route corresponding to current room name.
|
|
||||||
*
|
|
||||||
* @param {Object} state - Redux state.
|
|
||||||
* @private
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
function _navigate(state) {
|
|
||||||
const app = state['features/app'].app;
|
|
||||||
const routeToRender = _getRouteToRender(state);
|
|
||||||
|
|
||||||
app._navigate(routeToRender);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets room and navigates to new route if needed.
|
* Sets room and navigates to new route if needed.
|
||||||
*
|
*
|
||||||
|
@ -150,21 +147,15 @@ function _navigate(state) {
|
||||||
*/
|
*/
|
||||||
function _setRoomAndNavigate(newRoom) {
|
function _setRoomAndNavigate(newRoom) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const oldRoom = getState()['features/base/conference'].room;
|
|
||||||
|
|
||||||
dispatch(setRoom(newRoom));
|
dispatch(setRoom(newRoom));
|
||||||
|
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const { room } = state['features/base/conference'];
|
const { app } = state['features/app'];
|
||||||
const { landingIsShown } = state['features/unsupported-browser'];
|
const newRoute = _getRouteToRender(state);
|
||||||
|
|
||||||
// If the user agent is a mobile browser and landing hasn't been shown
|
if (!areRoutesEqual(newRoute, currentRoute)) {
|
||||||
// yet, we should recheck which component to render.
|
currentRoute = newRoute;
|
||||||
const OS = Platform.OS;
|
app._navigate(newRoute);
|
||||||
|
|
||||||
if (((OS === 'android' || OS === 'ios') && !landingIsShown)
|
|
||||||
|| room !== oldRoom) {
|
|
||||||
_navigate(state);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,17 +35,33 @@ export function _getRouteToRender(stateOrGetState) {
|
||||||
|
|
||||||
// If landing was shown, there is no need to show it again.
|
// If landing was shown, there is no need to show it again.
|
||||||
const { landingIsShown } = state['features/unsupported-browser'];
|
const { landingIsShown } = state['features/unsupported-browser'];
|
||||||
let component;
|
const { room } = state['features/base/conference'];
|
||||||
|
const component = isRoomValid(room) ? Conference : WelcomePage;
|
||||||
|
|
||||||
|
// We're using spread operator here to create copy of the route registered
|
||||||
|
// in registry. If we overwrite some of its properties (like 'component')
|
||||||
|
// they will stay unchanged in the registry.
|
||||||
|
const route = { ...RouteRegistry.getRouteByComponent(component) };
|
||||||
|
|
||||||
if ((OS === 'android' || OS === 'ios') && !landingIsShown) {
|
if ((OS === 'android' || OS === 'ios') && !landingIsShown) {
|
||||||
component = Landing;
|
route.component = Landing;
|
||||||
} else {
|
|
||||||
const { room } = state['features/base/conference'];
|
|
||||||
|
|
||||||
component = isRoomValid(room) ? Conference : WelcomePage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return RouteRegistry.getRouteByComponent(component);
|
return route;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method checking whether route objects are equal by value. Returns true if
|
||||||
|
* and only if key values of the first object are equal to key values of
|
||||||
|
* the second one.
|
||||||
|
*
|
||||||
|
* @param {Object} newRoute - New route object to be compared.
|
||||||
|
* @param {Object} oldRoute - Old route object to be compared.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
export function areRoutesEqual(newRoute, oldRoute) {
|
||||||
|
return Object.keys(newRoute)
|
||||||
|
.every(key => newRoute[key] === oldRoute[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { Link } from 'react-router';
|
|
||||||
|
|
||||||
import { Platform } from '../../base/react';
|
import { Platform } from '../../base/react';
|
||||||
|
|
||||||
|
import { appNavigate } from '../../app';
|
||||||
import { landingIsShown } from '../actions';
|
import { landingIsShown } from '../actions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,6 +21,20 @@ const URLS = {
|
||||||
* @class Landing
|
* @class Landing
|
||||||
*/
|
*/
|
||||||
class Landing extends Component {
|
class Landing extends Component {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor of Landing component.
|
||||||
|
*
|
||||||
|
* @param {Object} props - The read-only React Component props with which
|
||||||
|
* the new instance is to be initialized.
|
||||||
|
*/
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
// Bind methods
|
||||||
|
this._onClickJoin = this._onClickJoin.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Landing component's property types.
|
* Landing component's property types.
|
||||||
*
|
*
|
||||||
|
@ -48,7 +62,7 @@ class Landing extends Component {
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
const { room } = this.props;
|
const { room } = this.props;
|
||||||
let btnText;
|
let btnText;
|
||||||
let link = '/';
|
let link = '';
|
||||||
|
|
||||||
if (room) {
|
if (room) {
|
||||||
btnText = 'Join the conversation';
|
btnText = 'Join the conversation';
|
||||||
|
@ -63,13 +77,25 @@ class Landing extends Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigates to the next state of the app.
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_onClickJoin() {
|
||||||
|
const { link } = this.state;
|
||||||
|
|
||||||
|
this.props.dispatch(appNavigate(link));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders landing component.
|
* Renders landing component.
|
||||||
*
|
*
|
||||||
* @returns {ReactElement}
|
* @returns {ReactElement}
|
||||||
*/
|
*/
|
||||||
render() {
|
render() {
|
||||||
const { btnText, link } = this.state;
|
const { btnText } = this.state;
|
||||||
const primaryButtonClasses = 'landing__button landing__button_primary';
|
const primaryButtonClasses = 'landing__button landing__button_primary';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -92,11 +118,11 @@ class Landing extends Component {
|
||||||
<br />
|
<br />
|
||||||
<strong>then</strong>
|
<strong>then</strong>
|
||||||
</p>
|
</p>
|
||||||
<Link to = { link }>
|
<button
|
||||||
<button className = 'landing__button'>
|
className = 'landing__button'
|
||||||
{ btnText }
|
onClick = { this._onClickJoin }>
|
||||||
</button>
|
{ btnText }
|
||||||
</Link>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,4 +1,2 @@
|
||||||
import './route';
|
|
||||||
|
|
||||||
export * from './actions';
|
export * from './actions';
|
||||||
export * from './components';
|
export * from './components';
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
import { RouteRegistry } from '../base/navigator';
|
|
||||||
|
|
||||||
import { Landing } from './components';
|
|
||||||
|
|
||||||
RouteRegistry.register({
|
|
||||||
component: Landing,
|
|
||||||
path: '/mobile-app'
|
|
||||||
});
|
|
Loading…
Reference in New Issue