瀏覽代碼

Clean up routing logic

master
Ilya Daynatovich 8 年之前
父節點
當前提交
57ba702dda

+ 24
- 33
react/features/app/actions.js 查看文件

1
 import { setRoom } from '../base/conference';
1
 import { setRoom } from '../base/conference';
2
 import { getDomain, setDomain } from '../base/connection';
2
 import { getDomain, setDomain } from '../base/connection';
3
 import { loadConfig, setConfig } from '../base/lib-jitsi-meet';
3
 import { loadConfig, setConfig } from '../base/lib-jitsi-meet';
4
-import { Platform } from '../base/react';
5
 
4
 
6
 import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
5
 import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
7
 import {
6
 import {
8
     _getRoomAndDomainFromUrlString,
7
     _getRoomAndDomainFromUrlString,
9
     _getRouteToRender,
8
     _getRouteToRender,
9
+    areRoutesEqual,
10
     init
10
     init
11
 } from './functions';
11
 } from './functions';
12
 import './reducer';
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
  * Temporary solution. Should dispatch actions related to initial settings of
23
  * Temporary solution. Should dispatch actions related to initial settings of
16
  * the app like setting log levels, reading the config parameters from query
24
  * the app like setting log levels, reading the config parameters from query
42
         // current conference and start a new one with the new room name or
50
         // current conference and start a new one with the new room name or
43
         // domain.
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
             // If both domain and room vars became undefined, that means we're
54
             // If both domain and room vars became undefined, that means we're
49
             // actually dealing with just room name and not with URL.
55
             // actually dealing with just room name and not with URL.
50
             dispatch(
56
             dispatch(
63
             loadConfig(`https://${domain}`)
69
             loadConfig(`https://${domain}`)
64
                 .then(
70
                 .then(
65
                     config => configLoaded(/* err */ undefined, config),
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
                 return;
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
             dispatch(setConfig(config));
104
             dispatch(setConfig(config));
94
         }
105
         }
95
     };
106
     };
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
  * Sets room and navigates to new route if needed.
142
  * Sets room and navigates to new route if needed.
146
  *
143
  *
150
  */
147
  */
151
 function _setRoomAndNavigate(newRoom) {
148
 function _setRoomAndNavigate(newRoom) {
152
     return (dispatch, getState) => {
149
     return (dispatch, getState) => {
153
-        const oldRoom = getState()['features/base/conference'].room;
154
-
155
         dispatch(setRoom(newRoom));
150
         dispatch(setRoom(newRoom));
156
 
151
 
157
         const state = getState();
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 查看文件

35
 
35
 
36
     // If landing was shown, there is no need to show it again.
36
     // If landing was shown, there is no need to show it again.
37
     const { landingIsShown } = state['features/unsupported-browser'];
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 查看文件

1
 import React, { Component } from 'react';
1
 import React, { Component } from 'react';
2
 import { connect } from 'react-redux';
2
 import { connect } from 'react-redux';
3
-import { Link } from 'react-router';
4
 
3
 
5
 import { Platform } from '../../base/react';
4
 import { Platform } from '../../base/react';
6
 
5
 
6
+import { appNavigate } from '../../app';
7
 import { landingIsShown } from '../actions';
7
 import { landingIsShown } from '../actions';
8
 
8
 
9
 /**
9
 /**
21
  * @class Landing
21
  * @class Landing
22
  */
22
  */
23
 class Landing extends Component {
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
      * Landing component's property types.
39
      * Landing component's property types.
26
      *
40
      *
48
     componentWillMount() {
62
     componentWillMount() {
49
         const { room } = this.props;
63
         const { room } = this.props;
50
         let btnText;
64
         let btnText;
51
-        let link = '/';
65
+        let link = '';
52
 
66
 
53
         if (room) {
67
         if (room) {
54
             btnText = 'Join the conversation';
68
             btnText = 'Join the conversation';
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
      * Renders landing component.
93
      * Renders landing component.
68
      *
94
      *
69
      * @returns {ReactElement}
95
      * @returns {ReactElement}
70
      */
96
      */
71
     render() {
97
     render() {
72
-        const { btnText, link } = this.state;
98
+        const { btnText } = this.state;
73
         const primaryButtonClasses = 'landing__button landing__button_primary';
99
         const primaryButtonClasses = 'landing__button landing__button_primary';
74
 
100
 
75
         return (
101
         return (
92
                         <br />
118
                         <br />
93
                         <strong>then</strong>
119
                         <strong>then</strong>
94
                     </p>
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
                 </div>
126
                 </div>
101
             </div>
127
             </div>
102
         );
128
         );

+ 0
- 2
react/features/unsupported-browser/index.js 查看文件

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

+ 0
- 8
react/features/unsupported-browser/route.js 查看文件

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

Loading…
取消
儲存