Parcourir la source

Clean up routing logic

j8
Ilya Daynatovich il y a 8 ans
Parent
révision
57ba702dda

+ 24
- 33
react/features/app/actions.js Voir le fichier

@@ -1,16 +1,24 @@
1 1
 import { setRoom } from '../base/conference';
2 2
 import { getDomain, setDomain } from '../base/connection';
3 3
 import { loadConfig, setConfig } from '../base/lib-jitsi-meet';
4
-import { Platform } from '../base/react';
5 4
 
6 5
 import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
7 6
 import {
8 7
     _getRoomAndDomainFromUrlString,
9 8
     _getRouteToRender,
9
+    areRoutesEqual,
10 10
     init
11 11
 } from './functions';
12 12
 import './reducer';
13 13
 
14
+/**
15
+ * Variable saving current route of the app. Later it will be extracted as
16
+ * a property of the class with Router specific logic.
17
+ *
18
+ * @type {Object}
19
+ */
20
+let currentRoute = {};
21
+
14 22
 /**
15 23
  * Temporary solution. Should dispatch actions related to initial settings of
16 24
  * the app like setting log levels, reading the config parameters from query
@@ -42,9 +50,7 @@ export function appNavigate(urlOrRoom) {
42 50
         // current conference and start a new one with the new room name or
43 51
         // domain.
44 52
 
45
-        if (room === 'mobile-app') {
46
-            return;
47
-        } else if (typeof domain === 'undefined' || oldDomain === domain) {
53
+        if (typeof domain === 'undefined' || oldDomain === domain) {
48 54
             // If both domain and room vars became undefined, that means we're
49 55
             // actually dealing with just room name and not with URL.
50 56
             dispatch(
@@ -63,7 +69,15 @@ export function appNavigate(urlOrRoom) {
63 69
             loadConfig(`https://${domain}`)
64 70
                 .then(
65 71
                     config => configLoaded(/* err */ undefined, config),
66
-                    err => configLoaded(err, /* config */ undefined));
72
+                    err => configLoaded(err, /* config */ undefined))
73
+                .then(() => {
74
+                    const link = typeof room === 'undefined'
75
+                    && typeof domain === 'undefined'
76
+                        ? urlOrRoom
77
+                        : room;
78
+
79
+                    dispatch(_setRoomAndNavigate(link));
80
+                });
67 81
         }
68 82
 
69 83
         /**
@@ -87,9 +101,6 @@ export function appNavigate(urlOrRoom) {
87 101
                 return;
88 102
             }
89 103
 
90
-            // We set room name only here to prevent race conditions on app
91
-            // start to not make app re-render conference page for two times.
92
-            dispatch(setRoom(room));
93 104
             dispatch(setConfig(config));
94 105
         }
95 106
     };
@@ -127,20 +138,6 @@ export function appWillUnmount(app) {
127 138
     };
128 139
 }
129 140
 
130
-/**
131
- * Navigates to route corresponding to current room name.
132
- *
133
- * @param {Object} state - Redux state.
134
- * @private
135
- * @returns {void}
136
- */
137
-function _navigate(state) {
138
-    const app = state['features/app'].app;
139
-    const routeToRender = _getRouteToRender(state);
140
-
141
-    app._navigate(routeToRender);
142
-}
143
-
144 141
 /**
145 142
  * Sets room and navigates to new route if needed.
146 143
  *
@@ -150,21 +147,15 @@ function _navigate(state) {
150 147
  */
151 148
 function _setRoomAndNavigate(newRoom) {
152 149
     return (dispatch, getState) => {
153
-        const oldRoom = getState()['features/base/conference'].room;
154
-
155 150
         dispatch(setRoom(newRoom));
156 151
 
157 152
         const state = getState();
158
-        const { room } = state['features/base/conference'];
159
-        const { landingIsShown } = state['features/unsupported-browser'];
160
-
161
-        // If the user agent is a mobile browser and landing hasn't been shown
162
-        // yet, we should recheck which component to render.
163
-        const OS = Platform.OS;
153
+        const { app } = state['features/app'];
154
+        const newRoute = _getRouteToRender(state);
164 155
 
165
-        if (((OS === 'android' || OS === 'ios') && !landingIsShown)
166
-                || room !== oldRoom) {
167
-            _navigate(state);
156
+        if (!areRoutesEqual(newRoute, currentRoute)) {
157
+            currentRoute = newRoute;
158
+            app._navigate(newRoute);
168 159
         }
169 160
     };
170 161
 }

+ 23
- 7
react/features/app/functions.web.js Voir le fichier

@@ -35,17 +35,33 @@ export function _getRouteToRender(stateOrGetState) {
35 35
 
36 36
     // If landing was shown, there is no need to show it again.
37 37
     const { landingIsShown } = state['features/unsupported-browser'];
38
-    let component;
38
+    const { room } = state['features/base/conference'];
39
+    const component = isRoomValid(room) ? Conference : WelcomePage;
39 40
 
40
-    if ((OS === 'android' || OS === 'ios') && !landingIsShown) {
41
-        component = Landing;
42
-    } else {
43
-        const { room } = state['features/base/conference'];
41
+    // We're using spread operator here to create copy of the route registered
42
+    // in registry. If we overwrite some of its properties (like 'component')
43
+    // they will stay unchanged in the registry.
44
+    const route = { ...RouteRegistry.getRouteByComponent(component) };
44 45
 
45
-        component = isRoomValid(room) ? Conference : WelcomePage;
46
+    if ((OS === 'android' || OS === 'ios') && !landingIsShown) {
47
+        route.component = Landing;
46 48
     }
47 49
 
48
-    return RouteRegistry.getRouteByComponent(component);
50
+    return route;
51
+}
52
+
53
+/**
54
+ * Method checking whether route objects are equal by value. Returns true if
55
+ * and only if key values of the first object are equal to key values of
56
+ * the second one.
57
+ *
58
+ * @param {Object} newRoute - New route object to be compared.
59
+ * @param {Object} oldRoute - Old route object to be compared.
60
+ * @returns {boolean}
61
+ */
62
+export function areRoutesEqual(newRoute, oldRoute) {
63
+    return Object.keys(newRoute)
64
+        .every(key => newRoute[key] === oldRoute[key]);
49 65
 }
50 66
 
51 67
 /**

+ 34
- 8
react/features/unsupported-browser/components/Landing.js Voir le fichier

@@ -1,9 +1,9 @@
1 1
 import React, { Component } from 'react';
2 2
 import { connect } from 'react-redux';
3
-import { Link } from 'react-router';
4 3
 
5 4
 import { Platform } from '../../base/react';
6 5
 
6
+import { appNavigate } from '../../app';
7 7
 import { landingIsShown } from '../actions';
8 8
 
9 9
 /**
@@ -21,6 +21,20 @@ const URLS = {
21 21
  * @class Landing
22 22
  */
23 23
 class Landing extends Component {
24
+
25
+    /**
26
+     * Constructor of Landing component.
27
+     *
28
+     * @param {Object} props - The read-only React Component props with which
29
+     * the new instance is to be initialized.
30
+     */
31
+    constructor(props) {
32
+        super(props);
33
+
34
+        // Bind methods
35
+        this._onClickJoin = this._onClickJoin.bind(this);
36
+    }
37
+
24 38
     /**
25 39
      * Landing component's property types.
26 40
      *
@@ -48,7 +62,7 @@ class Landing extends Component {
48 62
     componentWillMount() {
49 63
         const { room } = this.props;
50 64
         let btnText;
51
-        let link = '/';
65
+        let link = '';
52 66
 
53 67
         if (room) {
54 68
             btnText = 'Join the conversation';
@@ -63,13 +77,25 @@ class Landing extends Component {
63 77
         });
64 78
     }
65 79
 
80
+    /**
81
+     * Navigates to the next state of the app.
82
+     *
83
+     * @returns {void}
84
+     * @private
85
+     */
86
+    _onClickJoin() {
87
+        const { link } = this.state;
88
+
89
+        this.props.dispatch(appNavigate(link));
90
+    }
91
+
66 92
     /**
67 93
      * Renders landing component.
68 94
      *
69 95
      * @returns {ReactElement}
70 96
      */
71 97
     render() {
72
-        const { btnText, link } = this.state;
98
+        const { btnText } = this.state;
73 99
         const primaryButtonClasses = 'landing__button landing__button_primary';
74 100
 
75 101
         return (
@@ -92,11 +118,11 @@ class Landing extends Component {
92 118
                         <br />
93 119
                         <strong>then</strong>
94 120
                     </p>
95
-                    <Link to = { link }>
96
-                        <button className = 'landing__button'>
97
-                            { btnText }
98
-                        </button>
99
-                    </Link>
121
+                    <button
122
+                        className = 'landing__button'
123
+                        onClick = { this._onClickJoin }>
124
+                        { btnText }
125
+                    </button>
100 126
                 </div>
101 127
             </div>
102 128
         );

+ 0
- 2
react/features/unsupported-browser/index.js Voir le fichier

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

+ 0
- 8
react/features/unsupported-browser/route.js Voir le fichier

@@ -1,8 +0,0 @@
1
-import { RouteRegistry } from '../base/navigator';
2
-
3
-import { Landing } from './components';
4
-
5
-RouteRegistry.register({
6
-    component: Landing,
7
-    path: '/mobile-app'
8
-});

Chargement…
Annuler
Enregistrer