Browse Source

[RN] Prepare to display BlankPage more

For example, while config.js and other files are being loaded before the
navigation to Conference is feasible.
master
Lyubo Marinov 7 years ago
parent
commit
45a1ae26ca

+ 7
- 7
react/features/app/actions.js View File

@@ -46,22 +46,22 @@ function _appNavigateToMandatoryLocation(
46 46
         .then(() => dispatch(setRoom(newLocation.room)));
47 47
 
48 48
     /**
49
-     * Notifies that an attempt to load a config(uration) has completed. Due to
50
-     * the asynchronous native of the loading, the specified <tt>config</tt> may
49
+     * Notifies that an attempt to load a configuration has completed. Due to
50
+     * the asynchronous nature of the loading, the specified <tt>config</tt> may
51 51
      * or may not be required by the time the notification arrives.
52 52
      *
53
-     * @param {string|undefined} err - If the loading has failed, the error
53
+     * @param {string|undefined} error - If the loading has failed, the error
54 54
      * detailing the cause of the failure.
55 55
      * @param {Object|undefined} config - If the loading has succeeded, the
56
-     * loaded config(uration).
56
+     * loaded configuration.
57 57
      * @returns {void}
58 58
      */
59
-    function configLoaded(err, config) {
60
-        // FIXME Due to the asynchronous native of the loading, the specified
59
+    function configLoaded(error, config) {
60
+        // FIXME Due to the asynchronous nature of the loading, the specified
61 61
         // config may or may not be required by the time the notification
62 62
         // arrives.
63 63
 
64
-        if (err) {
64
+        if (error) {
65 65
             // XXX The failure could be, for example, because of a
66 66
             // certificate-related error. In which case the connection will
67 67
             // fail later in Strophe anyway even if we use the default

+ 15
- 8
react/features/app/components/AbstractApp.js View File

@@ -13,6 +13,7 @@ import {
13 13
 import { RouteRegistry } from '../../base/react';
14 14
 import { MiddlewareRegistry, ReducerRegistry } from '../../base/redux';
15 15
 import { toURLString } from '../../base/util';
16
+import { BlankPage } from '../../welcome';
16 17
 
17 18
 import { appNavigate, appWillMount, appWillUnmount } from '../actions';
18 19
 
@@ -194,13 +195,14 @@ export class AbstractApp extends Component {
194 195
      */
195 196
     render() {
196 197
         const { route } = this.state;
198
+        const component = (route && route.component) || BlankPage;
197 199
 
198
-        if (route) {
200
+        if (component) {
199 201
             return (
200 202
                 <I18nextProvider i18n = { i18next }>
201 203
                     <Provider store = { this._getStore() }>
202 204
                         {
203
-                            this._createElement(route.component)
205
+                            this._createElement(component)
204 206
                         }
205 207
                     </Provider>
206 208
                 </I18nextProvider>
@@ -372,15 +374,20 @@ export class AbstractApp extends Component {
372 374
         // onEnter. During the removal of react-router, modifications were
373 375
         // minimized by preserving the onEnter interface:
374 376
         // (1) Router would provide its nextState to the Route's onEnter. As the
375
-        // role of Router is now this AbstractApp, provide its nextState.
377
+        // role of Router is now this AbstractApp and we use redux, provide the
378
+        // redux store instead.
376 379
         // (2) A replace function would be provided to the Route in case it
377 380
         // chose to redirect to another path.
378
-        route && this._onRouteEnter(route, nextState, pathname => {
379
-            this._openURL(pathname);
381
+        route && this._onRouteEnter(route, this._getStore(), pathname => {
382
+            if (pathname) {
383
+                this._openURL(pathname);
380 384
 
381
-            // Do not proceed with the route because it chose to redirect to
382
-            // another path.
383
-            nextState = undefined;
385
+                // Do not proceed with the route because it chose to redirect to
386
+                // another path.
387
+                nextState = undefined;
388
+            } else {
389
+                nextState.route = undefined;
390
+            }
384 391
         });
385 392
 
386 393
         // XXX React's setState is asynchronous which means that the value of

+ 1
- 1
react/features/app/functions.native.js View File

@@ -4,7 +4,7 @@ import { isRoomValid } from '../base/conference';
4 4
 import { RouteRegistry } from '../base/react';
5 5
 import { toState } from '../base/redux';
6 6
 import { Conference } from '../conference';
7
-import { Entryway } from '../welcome';
7
+import { WelcomePage } from '../welcome';
8 8
 
9 9
 /**
10 10
  * Determines which route is to be rendered in order to depict a specific Redux

+ 0
- 43
react/features/welcome/components/AbstractBlankPage.js View File

@@ -1,43 +0,0 @@
1
-import PropTypes from 'prop-types';
2
-import { Component } from 'react';
3
-
4
-import { destroyLocalTracks } from '../../base/tracks';
5
-
6
-/**
7
- * A React <tt>Component</tt> which represents a blank page. Destroys the local
8
- * tracks upon mounting since no media is desired when this component utilized.
9
- * Renders nothing.
10
- */
11
-export default class AbstractBlankPage extends Component {
12
-    /**
13
-     * <tt>AbstractBlankPage</tt> React <tt>Component</tt>'s prop types.
14
-     *
15
-     * @static
16
-     */
17
-    static propTypes = {
18
-        dispatch: PropTypes.func
19
-    };
20
-
21
-    /**
22
-     * Destroys the local tracks (if any) since no media is desired when this
23
-     * component is rendered.
24
-     *
25
-     * @inheritdoc
26
-     * @returns {void}
27
-     */
28
-    componentWillMount() {
29
-        this.props.dispatch(destroyLocalTracks());
30
-    }
31
-
32
-    /**
33
-     * Implements React's {@link Component#render()}. Returns null because the
34
-     * purpose of this component is to destroy the local tracks and render
35
-     * nothing.
36
-     *
37
-     * @inheritdoc
38
-     * @returns {null}
39
-     */
40
-    render() {
41
-        return null;
42
-    }
43
-}

+ 35
- 14
react/features/welcome/components/BlankPage.native.js View File

@@ -1,39 +1,58 @@
1 1
 /* @flow */
2 2
 
3 3
 import PropTypes from 'prop-types';
4
-import React from 'react';
4
+import React, { Component } from 'react';
5 5
 import { ActivityIndicator, View } from 'react-native';
6 6
 import { connect } from 'react-redux';
7 7
 
8
-import AbstractBlankPage from './AbstractBlankPage';
8
+import { destroyLocalTracks } from '../../base/tracks';
9
+
10
+import { isWelcomePageAppEnabled } from '../functions';
9 11
 import styles from './styles';
10 12
 
11 13
 /**
12
- * Mobile/React Native implementation of <tt>AbstractBlankPage</tt>. Since this
13
- * is the <tt>Component</tt> rendered when there is no <tt>WelcomePage</tt>,
14
- * it will show a progress indicator when there are ongoing network requests
15
- * (notably, the loading of config.js before joining a conference). The use case
16
- * which prompted the introduction of this <tt>Component</tt> is mobile where
17
- * SDK users probably disable the <tt>WelcomePage</tt>.
14
+ * The React <tt>Component</tt> displayed by <tt>AbstractApp</tt> when it has no
15
+ * <tt>Route</tt> to render. Renders a progress indicator when there are ongoing
16
+ * network requests.
18 17
  */
19
-class BlankPage extends AbstractBlankPage {
18
+class BlankPage extends Component {
20 19
     /**
21 20
      * <tt>BlankPage</tt> React <tt>Component</tt>'s prop types.
22 21
      *
23 22
      * @static
24 23
      */
25 24
     static propTypes = {
26
-        ...AbstractBlankPage.propTypes,
27
-
28 25
         /**
29 26
          * Indicates whether there is network activity i.e. ongoing network
30 27
          * requests.
31 28
          *
32 29
          * @private
33 30
          */
34
-        _networkActivity: PropTypes.bool
31
+        _networkActivity: PropTypes.bool,
32
+
33
+        /**
34
+         * The indicator which determines whether <tt>WelcomePage</tt> is (to
35
+         * be) rendered.
36
+         *
37
+         * @private
38
+         */
39
+        _welcomePageEnabled: PropTypes.bool,
40
+
41
+        dispatch: PropTypes.func
35 42
     };
36 43
 
44
+    /**
45
+     * Destroys the local tracks (if any) since no media is desired when this
46
+     * component is rendered.
47
+     *
48
+     * @inheritdoc
49
+     * @returns {void}
50
+     */
51
+    componentWillMount() {
52
+        this.props._welcomePageEnabled
53
+            || this.props.dispatch(destroyLocalTracks());
54
+    }
55
+
37 56
     /**
38 57
      * Implements React's {@link Component#render()}.
39 58
      *
@@ -59,7 +78,8 @@ class BlankPage extends AbstractBlankPage {
59 78
  * @param {Object} state - The redux state.
60 79
  * @private
61 80
  * @returns {{
62
- *     networkActivity: boolean
81
+ *     _networkActivity: boolean,
82
+ *     _welcomePageEnabled: boolean
63 83
  * }}
64 84
  */
65 85
 function _mapStateToProps(state) {
@@ -67,7 +87,8 @@ function _mapStateToProps(state) {
67 87
 
68 88
     return {
69 89
         _networkActivity:
70
-            Boolean(requests && (requests.length || requests.size))
90
+            Boolean(requests && (requests.length || requests.size)),
91
+        _welcomePageEnabled: isWelcomePageAppEnabled(state)
71 92
     };
72 93
 }
73 94
 

+ 1
- 10
react/features/welcome/components/BlankPage.web.js View File

@@ -1,10 +1 @@
1
-import AbstractBlankPage from './AbstractBlankPage';
2
-
3
-/**
4
- * Default <tt>BlankPage</tt> implementation for Web/React. It's not currently
5
- * in use but it's here for symmetry with mobile/React Native should we choose
6
- * to take advantage of it in the future. Destroys the local tracks and renders
7
- * nothing.
8
- */
9
-export default class BlankPage extends AbstractBlankPage {
10
-}
1
+export default undefined;

+ 0
- 74
react/features/welcome/components/Entryway.js View File

@@ -1,74 +0,0 @@
1
-import PropTypes from 'prop-types';
2
-import React, { Component } from 'react';
3
-import { connect } from 'react-redux';
4
-
5
-import BlankPage from './BlankPage';
6
-import WelcomePage from './WelcomePage';
7
-
8
-/**
9
- * A React <tt>Component</tt> which is rendered when there is no (valid) room
10
- * (name) i.e. it is the opposite of <tt>Conference</tt>. Generally and
11
- * historically, it is <tt>WelcomePage</tt>. However, Jitsi Meet SDK for Android
12
- * and iOS allows the use of the (JavaScript) app without <tt>WelcomePage</tt>
13
- * and it needs to display something between conferences.
14
- */
15
-class Entryway extends Component {
16
-    /**
17
-     * <tt>Entryway</tt>'s React <tt>Component</tt> prop types.
18
-     */
19
-    static propTypes = {
20
-        /**
21
-         * The indicator which determines whether <tt>WelcomePage</tt> is (to
22
-         * be) rendered.
23
-         *
24
-         * @private
25
-         */
26
-        _welcomePageEnabled: PropTypes.bool
27
-    };
28
-
29
-    /**
30
-     * Implements React's {@link Component#render()}.
31
-     *
32
-     * @inheritdoc
33
-     * @returns {ReactElement}
34
-     */
35
-    render() {
36
-        return (
37
-            this.props._welcomePageEnabled ? <WelcomePage /> : <BlankPage />
38
-        );
39
-    }
40
-}
41
-
42
-/**
43
- * Maps (parts of) the redux state to the associated Entryway's props.
44
- *
45
- * @param {Object} state - The redux state.
46
- * @private
47
- * @returns {{
48
- *     _welcomePageEnabled: boolean
49
- * }}
50
- */
51
-function _mapStateToProps(state) {
52
-    let welcomePageEnabled;
53
-
54
-    if (navigator.product === 'ReactNative') {
55
-        // We introduced the welcomePageEnabled prop on App in Jitsi Meet SDK
56
-        // for Android and iOS. There isn't a strong reason not to introduce it
57
-        // on Web but there're a few considerations to be taken before I go
58
-        // there among which:
59
-        // - Enabling/disabling the Welcome page on Web historically
60
-        // automatically redirects to a random room and that does not make sense
61
-        // on mobile (right now).
62
-        const { app } = state['features/app'];
63
-
64
-        welcomePageEnabled = Boolean(app && app.props.welcomePageEnabled);
65
-    } else {
66
-        welcomePageEnabled = true;
67
-    }
68
-
69
-    return {
70
-        _welcomePageEnabled: welcomePageEnabled
71
-    };
72
-}
73
-
74
-export default connect(_mapStateToProps)(Entryway);

+ 0
- 1
react/features/welcome/components/index.js View File

@@ -1,3 +1,2 @@
1 1
 export { default as BlankPage } from './BlankPage';
2
-export { default as Entryway } from './Entryway';
3 2
 export { default as WelcomePage } from './WelcomePage';

+ 57
- 0
react/features/welcome/functions.js View File

@@ -0,0 +1,57 @@
1
+/* @flow */
2
+
3
+import { toState } from '../base/redux';
4
+
5
+declare var APP: Object;
6
+declare var config: Object;
7
+
8
+export * from './roomnameGenerator';
9
+
10
+/**
11
+ * Determines whether the <tt>WelcomePage</tt> is enabled by the app itself
12
+ * (e.g. programmatically via the Jitsi Meet SDK for Android and iOS). Not to be
13
+ * confused with {@link isWelcomePageUserEnabled}.
14
+ *
15
+ * @param {Object|Function} stateOrGetState - The redux state or
16
+ * {@link getState} function.
17
+ * @returns {boolean} If the <tt>WelcomePage</tt> is enabled by the app, then
18
+ * <tt>true</tt>; otherwise, <tt>false</tt>.
19
+ */
20
+export function isWelcomePageAppEnabled(stateOrGetState: Object | Function) {
21
+    let b;
22
+
23
+    if (navigator.product === 'ReactNative') {
24
+        // We introduced the welcomePageEnabled prop on App in Jitsi Meet SDK
25
+        // for Android and iOS. There isn't a strong reason not to introduce it
26
+        // on Web but there're a few considerations to be taken before I go
27
+        // there among which:
28
+        // - Enabling/disabling the Welcome page on Web historically
29
+        // automatically redirects to a random room and that does not make sense
30
+        // on mobile (right now).
31
+        const { app } = toState(stateOrGetState)['features/app'];
32
+
33
+        b = Boolean(app && app.props.welcomePageEnabled);
34
+    } else {
35
+        b = true;
36
+    }
37
+
38
+    return b;
39
+}
40
+
41
+/**
42
+ * Determines whether the <tt>WelcomePage</tt> is enabled by the user either
43
+ * herself or through her deployment config(uration). Not to be confused with
44
+ * {@link isWelcomePageAppEnabled}.
45
+ *
46
+ * @param {Object|Function} stateOrGetState - The redux state or
47
+ * {@link getState} function.
48
+ * @returns {boolean} If the <tt>WelcomePage</tt> is enabled by the user, then
49
+ * <tt>true</tt>; otherwise, <tt>false</tt>.
50
+ */
51
+export function isWelcomePageUserEnabled(stateOrGetState: Object | Function) {
52
+    return (
53
+        typeof APP === 'undefined'
54
+            ? true
55
+            : toState(stateOrGetState)['features/base/config'].enableWelcomePage
56
+                && APP.settings.isWelcomePageEnabled());
57
+}

+ 1
- 0
react/features/welcome/index.js View File

@@ -1,3 +1,4 @@
1 1
 import './route';
2 2
 
3 3
 export * from './components';
4
+export * from './functions';

+ 16
- 29
react/features/welcome/route.js View File

@@ -2,47 +2,34 @@
2 2
 
3 3
 import { RouteRegistry } from '../base/react';
4 4
 
5
-import { Entryway } from './components';
6
-import { generateRoomWithoutSeparator } from './roomnameGenerator';
7
-
8
-declare var APP: Object;
9
-declare var config: Object;
5
+import { WelcomePage } from './components';
6
+import {
7
+    generateRoomWithoutSeparator,
8
+    isWelcomePageAppEnabled,
9
+    isWelcomePageUserEnabled
10
+} from './functions';
10 11
 
11 12
 /**
12
- * Register route for Entryway.
13
+ * Register route for <tt>WelcomePage</tt>.
13 14
  */
14 15
 RouteRegistry.register({
15
-    component: Entryway,
16
+    component: WelcomePage,
16 17
     onEnter,
17 18
     path: '/'
18 19
 });
19 20
 
20 21
 /**
21
- * If the Welcome page/screen is disabled, generates a (random) room (name) so
22
- * that the Welcome page/screen is skipped and the Conference page/screen is
23
- * presented instead.
22
+ * Skips the <tt>WelcomePage</tt> if it is disabled (by the app or the user).
24 23
  *
25
- * @param {Object} nextState - The next Router state.
24
+ * @param {Object} store - The redux store.
26 25
  * @param {Function} replace - The function to redirect to another path.
27 26
  * @returns {void}
28 27
  */
29
-function onEnter(nextState, replace) {
30
-    // The disabling of the Welcome page by redirecting to a random room name is
31
-    // a feature (1) we have on Web/React and (2) we do not want on mobile/React
32
-    // Native (at the time of this writing).
33
-    if (typeof APP === 'object'
34
-
35
-            // TODO Technically, there is features/base/config now so it is
36
-            // preferable to read config(uration) values from there and not rely
37
-            // on a global variable. However, the redux store is not available
38
-            // here at the time of this writing. Given the current (1) Web
39
-            // exclusivity of the feature and (2) the reliance on other global
40
-            // variables (e.g. APP), go with the global variable for now in
41
-            // order to minimize the effort involved.
42
-            && !(config.enableWelcomePage
43
-                && APP.settings.isWelcomePageEnabled())) {
44
-        const room = generateRoomWithoutSeparator();
45
-
46
-        replace(`/${room}`);
28
+function onEnter({ getState }, replace) {
29
+    if (isWelcomePageAppEnabled(getState)) {
30
+        isWelcomePageUserEnabled(getState)
31
+            || replace(`/${generateRoomWithoutSeparator()}`);
32
+    } else {
33
+        replace(undefined);
47 34
     }
48 35
 }

Loading…
Cancel
Save