From 0b8c12de0ef129838870a2478db774a98f7fc045 Mon Sep 17 00:00:00 2001 From: Lyubo Marinov Date: Tue, 22 Aug 2017 12:28:31 -0500 Subject: [PATCH] Simplify route navigation I see it as the first step in simplifying the route navigate of the JavaScript app by removing BlankWelcomePage from _getRouteToRender. From a faraway point of view, the app is at the route at which it is not in a conference. Historically, the route was known as the Welcome page. But mobile complicated the route by saying that actually it may not want to see the room name input and join button. Additionally, I renamed BlankWelcomePage to BlankPage because I don't think of it as a WelcomePage alternative but rather as a more generic BlankPage which may be utilized elsewhere in the future. I plan for the next steps to: * Merge Entryway, _interceptComponent, and _getRouteToRender in one React Component rendered by AbstractApp so that the whole logic is in one file; * Get rid of RouteRegistry and routes. --- react/features/app/functions.native.js | 23 ++---- react/features/app/functions.web.js | 29 +++----- .../{BlankWelcomePage.js => BlankPage.js} | 14 ++-- react/features/welcome/components/Entryway.js | 74 +++++++++++++++++++ react/features/welcome/components/index.js | 3 +- react/features/welcome/route.js | 15 +--- 6 files changed, 102 insertions(+), 56 deletions(-) rename react/features/welcome/components/{BlankWelcomePage.js => BlankPage.js} (65%) create mode 100644 react/features/welcome/components/Entryway.js diff --git a/react/features/app/functions.native.js b/react/features/app/functions.native.js index 0807fdc05..025e3bc2a 100644 --- a/react/features/app/functions.native.js +++ b/react/features/app/functions.native.js @@ -1,7 +1,9 @@ +/* @flow */ + import { isRoomValid } from '../base/conference'; import { RouteRegistry } from '../base/react'; import { Conference } from '../conference'; -import { BlankWelcomePage, WelcomePage } from '../welcome'; +import { Entryway } from '../welcome'; /** * Determines which route is to be rendered in order to depict a specific Redux @@ -11,28 +13,13 @@ import { BlankWelcomePage, WelcomePage } from '../welcome'; * method. * @returns {Route} */ -export function _getRouteToRender(stateOrGetState) { +export function _getRouteToRender(stateOrGetState: Object | Function) { const state = typeof stateOrGetState === 'function' ? stateOrGetState() : stateOrGetState; const { room } = state['features/base/conference']; - let component; - - if (isRoomValid(room)) { - component = Conference; - } else { - // The value of the App prop welcomePageEnabled was stored in redux in - // saghul's PR. But I removed the redux state, action, action type, etc. - // because I didn't like the name. We are not using the prop is a - // React-ive way anyway so it's all the same difference. - const { app } = state['features/app']; - - component - = app && app.props.welcomePageEnabled - ? WelcomePage - : BlankWelcomePage; - } + const component = isRoomValid(room) ? Conference : Entryway; return RouteRegistry.getRouteByComponent(component); } diff --git a/react/features/app/functions.web.js b/react/features/app/functions.web.js index 6eb0ea97d..8a08e49c6 100644 --- a/react/features/app/functions.web.js +++ b/react/features/app/functions.web.js @@ -1,15 +1,17 @@ /* @flow */ -import { isRoomValid } from '../base/conference'; -import { Platform, RouteRegistry } from '../base/react'; -import { Conference } from '../conference'; +import { Platform } from '../base/react'; import { NoMobileApp, PluginRequiredBrowser, UnsupportedDesktopBrowser, UnsupportedMobileBrowser } from '../unsupported-browser'; -import { WelcomePage } from '../welcome'; + +import { + // eslint-disable-next-line camelcase + _getRouteToRender as _super_getRouteToRender +} from './functions.native'; declare var APP: Object; declare var interfaceConfig: Object; @@ -61,8 +63,7 @@ const _INTERCEPT_COMPONENT_RULES = [ break; case 'undefined': - // If webRTCReady is not set, then we cannot use it to take a - // decision. + // If webRTCReady is not set, then we cannot base a decision on it. break; default: @@ -80,19 +81,11 @@ const _INTERCEPT_COMPONENT_RULES = [ * @returns {Route} */ export function _getRouteToRender(stateOrGetState: Object | Function) { - const state - = typeof stateOrGetState === 'function' - ? stateOrGetState() - : stateOrGetState; + const route = _super_getRouteToRender(stateOrGetState); - // If mobile browser page was shown, there is no need to show it again. - const { room } = state['features/base/conference']; - const component = isRoomValid(room) ? Conference : WelcomePage; - const route = RouteRegistry.getRouteByComponent(component); - - // Intercepts route components if any of component interceptor rules - // is satisfied. - route.component = _interceptComponent(state, component); + // Intercepts route components if any of component interceptor rules is + // satisfied. + route.component = _interceptComponent(stateOrGetState, route.component); return route; } diff --git a/react/features/welcome/components/BlankWelcomePage.js b/react/features/welcome/components/BlankPage.js similarity index 65% rename from react/features/welcome/components/BlankWelcomePage.js rename to react/features/welcome/components/BlankPage.js index b2651f418..cc6ae3834 100644 --- a/react/features/welcome/components/BlankWelcomePage.js +++ b/react/features/welcome/components/BlankPage.js @@ -5,16 +5,16 @@ import { connect } from 'react-redux'; import { destroyLocalTracks } from '../../base/tracks'; /** - * Component for rendering a blank welcome page. It renders absolutely nothing - * and destroys local tracks upon being mounted, since no media is desired when + * A React Component which represents a blank page. It renders nothing + * and destroys local tracks upon being mounted since no media is desired when * this component is rendered. * - * The use case is mainly mobile, where SDK users probably disable the welcome - * page, but using it on the web in the future is not out of the question. + * The use case which prompted the introduction of this component is mobile + * where SDK users probably disable the Welcome page. */ -class BlankWelcomePage extends Component { +class BlankPage extends Component { /** - * {@code BlankWelcomePage} component's property types. + * {@code BlankPage} component's property types. * * @static */ @@ -46,4 +46,4 @@ class BlankWelcomePage extends Component { } } -export default connect()(BlankWelcomePage); +export default connect()(BlankPage); diff --git a/react/features/welcome/components/Entryway.js b/react/features/welcome/components/Entryway.js new file mode 100644 index 000000000..300410882 --- /dev/null +++ b/react/features/welcome/components/Entryway.js @@ -0,0 +1,74 @@ +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { connect } from 'react-redux'; + +import BlankPage from './BlankPage'; +import WelcomePage from './WelcomePage'; + +/** + * A React Component which is rendered when there is no (valid) room + * (name) i.e. it is the opposite of Conference. Generally and + * historically, it is WelcomePage. However, Jitsi Meet SDK for Android + * and iOS allows the use of the (JavaScript) app without WelcomePage + * and it needs to display something between conferences. + */ +class Entryway extends Component { + /** + * Entryway's React Component prop types. + */ + static propTypes = { + /** + * The indicator which determines whether WelcomePage is (to + * be) rendered. + * + * @private + */ + _welcomePageEnabled: PropTypes.bool + }; + + /** + * Implements React's {@link Component#render()}. + * + * @inheritdoc + * @returns {ReactElement} + */ + render() { + return ( + this.props._welcomePageEnabled ? : + ); + } +} + +/** + * Maps (parts of) the redux state to the associated Entryway's props. + * + * @param {Object} state - The redux state. + * @private + * @returns {{ + * _welcomePageEnabled: boolean + * }} + */ +function _mapStateToProps(state) { + let welcomePageEnabled; + + if (navigator.product === 'ReactNative') { + // We introduced the welcomePageEnabled prop on App in Jitsi Meet SDK + // for Android and iOS. There isn't a strong reason not to introduce it + // on Web but there're a few considerations to be taken before I go + // there among which: + // - Enabling/disabling the Welcome page on Web historically + // automatically redirects to a random room and that does not make sense + // on mobile (right now). + const { app } = state['features/app']; + + welcomePageEnabled = Boolean(app && app.props.welcomePageEnabled); + } else { + welcomePageEnabled = true; + } + + return { + _welcomePageEnabled: welcomePageEnabled + }; +} + +export default connect(_mapStateToProps)(Entryway); diff --git a/react/features/welcome/components/index.js b/react/features/welcome/components/index.js index c23d36edf..3e70d4236 100644 --- a/react/features/welcome/components/index.js +++ b/react/features/welcome/components/index.js @@ -1,2 +1,3 @@ -export { default as BlankWelcomePage } from './BlankWelcomePage'; +export { default as BlankPage } from './BlankPage'; +export { default as Entryway } from './Entryway'; export { default as WelcomePage } from './WelcomePage'; diff --git a/react/features/welcome/route.js b/react/features/welcome/route.js index 808a2b564..02fe50ae8 100644 --- a/react/features/welcome/route.js +++ b/react/features/welcome/route.js @@ -2,26 +2,17 @@ import { RouteRegistry } from '../base/react'; -import { BlankWelcomePage, WelcomePage } from './components'; +import { Entryway } from './components'; import { generateRoomWithoutSeparator } from './roomnameGenerator'; declare var APP: Object; declare var config: Object; /** - * Register route for BlankWelcomePage. + * Register route for Entryway. */ RouteRegistry.register({ - component: BlankWelcomePage, - undefined, - path: '/#blank' -}); - -/** - * Register route for WelcomePage. - */ -RouteRegistry.register({ - component: WelcomePage, + component: Entryway, onEnter, path: '/' });