Bläddra i källkod

Fix d17cc9fa

A bug was discovered in d17cc9fa which would raise a failure to push
into the browser's history if a base href was defined. Fix the failure
by removing react-router. Anyway, the usage of react-router was
incorrect because the app must hit the server infrastructure when it
enters a room because the server will choose the very app version then.
j8
Lyubomir Marinov 8 år sedan
förälder
incheckning
ba3d65c01f

+ 0
- 2
package.json Visa fil

@@ -39,8 +39,6 @@
39 39
     "react-native-vector-icons": "^3.0.0",
40 40
     "react-native-webrtc": "jitsi/react-native-webrtc",
41 41
     "react-redux": "^5.0.2",
42
-    "react-router": "^3.0.0",
43
-    "react-router-redux": "^4.0.7",
44 42
     "redux": "^3.5.2",
45 43
     "redux-thunk": "^2.1.0",
46 44
     "retry": "0.6.1",

+ 94
- 0
react/features/app/components/AbstractApp.js Visa fil

@@ -1,4 +1,5 @@
1 1
 import React, { Component } from 'react';
2
+import { Provider } from 'react-redux';
2 3
 
3 4
 import {
4 5
     localParticipantJoined,
@@ -32,6 +33,25 @@ export class AbstractApp extends Component {
32 33
         url: React.PropTypes.string
33 34
     }
34 35
 
36
+    /**
37
+     * Initializes a new App instance.
38
+     *
39
+     * @param {Object} props - The read-only React Component props with which
40
+     * the new instance is to be initialized.
41
+     */
42
+    constructor(props) {
43
+        super(props);
44
+
45
+        this.state = {
46
+            /**
47
+             * The Route rendered by this App.
48
+             *
49
+             * @type {Route}
50
+             */
51
+            route: undefined
52
+        };
53
+    }
54
+
35 55
     /**
36 56
      * Init lib-jitsi-meet and create local participant when component is going
37 57
      * to be mounted.
@@ -62,6 +82,28 @@ export class AbstractApp extends Component {
62 82
         dispatch(appWillUnmount(this));
63 83
     }
64 84
 
85
+    /**
86
+     * Implements React's {@link Component#render()}.
87
+     *
88
+     * @inheritdoc
89
+     * @returns {ReactElement}
90
+     */
91
+    render() {
92
+        const route = this.state.route;
93
+
94
+        if (route) {
95
+            return (
96
+                <Provider store = { this.props.store }>
97
+                    {
98
+                        this._createElement(route.component)
99
+                    }
100
+                </Provider>
101
+            );
102
+        }
103
+
104
+        return null;
105
+    }
106
+
65 107
     /**
66 108
      * Create a ReactElement from the specified component, the specified props
67 109
      * and the props of this AbstractApp which are suitable for propagation to
@@ -161,6 +203,58 @@ export class AbstractApp extends Component {
161 203
         return undefined;
162 204
     }
163 205
 
206
+    /**
207
+     * Navigates to a specific Route.
208
+     *
209
+     * @param {Route} route - The Route to which to navigate.
210
+     * @returns {void}
211
+     */
212
+    _navigate(route) {
213
+        let nextState = {
214
+            ...this.state,
215
+            route
216
+        };
217
+
218
+        // The Web App was using react-router so it utilized react-router's
219
+        // onEnter. During the removal of react-router, modifications were
220
+        // minimized by preserving the onEnter interface:
221
+        // (1) Router would provide its nextState to the Route's onEnter. As the
222
+        // role of Router is now this AbstractApp, provide its nextState.
223
+        // (2) A replace function would be provided to the Route in case it
224
+        // chose to redirect to another path.
225
+        this._onRouteEnter(route, nextState, pathname => {
226
+            // FIXME In order to minimize the modifications related to the
227
+            // removal of react-router, the Web implementation is provided
228
+            // bellow because the replace function is used on Web only at the
229
+            // time of this writing. Provide a platform-agnostic implementation.
230
+            // It should likely find the best Route matching the specified
231
+            // pathname and navigate to it.
232
+            window.location.pathname = pathname;
233
+
234
+            // Do not proceed with the route because it chose to redirect to
235
+            // another path.
236
+            nextState = undefined;
237
+        });
238
+
239
+        nextState && this.setState(nextState);
240
+    }
241
+
242
+    /**
243
+     * Notifies this App that a specific Route is about to be rendered.
244
+     *
245
+     * @param {Route} route - The Route that is about to be rendered.
246
+     * @private
247
+     * @returns {void}
248
+     */
249
+    _onRouteEnter(route, ...args) {
250
+        // Notify the route that it is about to be entered.
251
+        const onEnter = route.onEnter;
252
+
253
+        if (typeof onEnter === 'function') {
254
+            onEnter(...args);
255
+        }
256
+    }
257
+
164 258
     /**
165 259
      * Navigates this AbstractApp to (i.e. opens) a specific URL.
166 260
      *

+ 1
- 64
react/features/app/components/App.native.js Visa fil

@@ -1,12 +1,9 @@
1 1
 /* global __DEV__ */
2 2
 
3
-import React from 'react';
4
-import { Linking, Navigator } from 'react-native';
5
-import { Provider } from 'react-redux';
3
+import { Linking } from 'react-native';
6 4
 
7 5
 import { Platform } from '../../base/react';
8 6
 
9
-import { _getRouteToRender } from '../functions';
10 7
 import { AbstractApp } from './AbstractApp';
11 8
 
12 9
 /**
@@ -32,7 +29,6 @@ export class App extends AbstractApp {
32 29
         super(props);
33 30
 
34 31
         // Bind event handlers so they are only bound once for every instance.
35
-        this._navigatorRenderScene = this._navigatorRenderScene.bind(this);
36 32
         this._onLinkingURL = this._onLinkingURL.bind(this);
37 33
 
38 34
         // In the Release configuration, React Native will (intentionally) throw
@@ -70,47 +66,6 @@ export class App extends AbstractApp {
70 66
         super.componentWillUnmount();
71 67
     }
72 68
 
73
-    /**
74
-     * Implements React's {@link Component#render()}.
75
-     *
76
-     * @inheritdoc
77
-     * @returns {ReactElement}
78
-     */
79
-    render() {
80
-        const store = this.props.store;
81
-
82
-        /* eslint-disable brace-style, react/jsx-no-bind */
83
-
84
-        return (
85
-            <Provider store = { store }>
86
-                <Navigator
87
-                    initialRoute = { _getRouteToRender(store.getState) }
88
-                    ref = { navigator => { this.navigator = navigator; } }
89
-                    renderScene = { this._navigatorRenderScene } />
90
-            </Provider>
91
-        );
92
-
93
-        /* eslint-enable brace-style, react/jsx-no-bind */
94
-    }
95
-
96
-    /**
97
-     * Navigates to a specific Route (via platform-specific means).
98
-     *
99
-     * @param {Route} route - The Route to which to navigate.
100
-     * @returns {void}
101
-     */
102
-    _navigate(route) {
103
-        const navigator = this.navigator;
104
-
105
-        // TODO Currently, the replace method doesn't support animation. Work
106
-        // towards adding it is done in
107
-        // https://github.com/facebook/react-native/issues/1981
108
-        // XXX React Native's Navigator adds properties to the route it's
109
-        // provided with. Clone the specified route in order to prevent its
110
-        // modification.
111
-        navigator && navigator.replace({ ...route });
112
-    }
113
-
114 69
     /**
115 70
      * Attempts to disable the use of React Native
116 71
      * {@link ExceptionsManager#handleException} on platforms and in
@@ -149,24 +104,6 @@ export class App extends AbstractApp {
149 104
         }
150 105
     }
151 106
 
152
-    /**
153
-     * Renders the scene identified by a specific route in the Navigator of this
154
-     * instance.
155
-     *
156
-     * @param {Object} route - The route which identifies the scene to be
157
-     * rendered in the associated Navigator. In the fashion of NavigatorIOS, the
158
-     * specified route is expected to define a value for its component property
159
-     * which is the type of React component to be rendered.
160
-     * @private
161
-     * @returns {ReactElement}
162
-     */
163
-    _navigatorRenderScene(route) {
164
-        // We started with NavigatorIOS and then switched to Navigator in order
165
-        // to support Android as well. In order to reduce the number of
166
-        // modifications, accept the same format of route definition.
167
-        return this._createElement(route.component, {});
168
-    }
169
-
170 107
     /**
171 108
      * Notified by React's Linking API that a specific URL registered to be
172 109
      * handled by this App was activated.

+ 14
- 122
react/features/app/components/App.web.js Visa fil

@@ -1,10 +1,3 @@
1
-import React from 'react';
2
-import { Provider } from 'react-redux';
3
-import { browserHistory, Route, Router } from 'react-router';
4
-import { push, replace, syncHistoryWithStore } from 'react-router-redux';
5
-
6
-import { RouteRegistry } from '../../base/navigator';
7
-
8 1
 import { appInit } from '../actions';
9 2
 import { AbstractApp } from './AbstractApp';
10 3
 
@@ -21,26 +14,6 @@ export class App extends AbstractApp {
21 14
      */
22 15
     static propTypes = AbstractApp.propTypes
23 16
 
24
-    /**
25
-     * Initializes a new App instance.
26
-     *
27
-     * @param {Object} props - The read-only React Component props with which
28
-     * the new instance is to be initialized.
29
-     */
30
-    constructor(props) {
31
-        super(props);
32
-
33
-        /**
34
-         * Create an enhanced history that syncs navigation events with the
35
-         * store.
36
-         * @link https://github.com/reactjs/react-router-redux#how-it-works
37
-         */
38
-        this.history = syncHistoryWithStore(browserHistory, props.store);
39
-
40
-        // Bind event handlers so they are only bound once for every instance.
41
-        this._routerCreateElement = this._routerCreateElement.bind(this);
42
-    }
43
-
44 17
     /**
45 18
      * Inits the app before component will mount.
46 19
      *
@@ -52,26 +25,6 @@ export class App extends AbstractApp {
52 25
         this.props.store.dispatch(appInit());
53 26
     }
54 27
 
55
-    /**
56
-     * Implements React's {@link Component#render()}.
57
-     *
58
-     * @inheritdoc
59
-     * @returns {ReactElement}
60
-     */
61
-    render() {
62
-        return (
63
-            <Provider store = { this.props.store }>
64
-                <Router
65
-                    createElement = { this._routerCreateElement }
66
-                    history = { this.history }>
67
-                    {
68
-                        this._renderRoutes()
69
-                    }
70
-                </Router>
71
-            </Provider>
72
-        );
73
-    }
74
-
75 28
     /**
76 29
      * Gets a Location object from the window with information about the current
77 30
      * location of the document.
@@ -86,6 +39,7 @@ export class App extends AbstractApp {
86 39
      * Navigates to a specific Route (via platform-specific means).
87 40
      *
88 41
      * @param {Route} route - The Route to which to navigate.
42
+     * @protected
89 43
      * @returns {void}
90 44
      */
91 45
     _navigate(route) {
@@ -100,81 +54,19 @@ export class App extends AbstractApp {
100 54
                 /:room/g,
101 55
                 store.getState()['features/base/conference'].room);
102 56
 
103
-        return (
104
-            store.dispatch(
105
-                    (window.location.pathname === path ? replace : push)(
106
-                            path)));
107
-    }
108
-
109
-    /**
110
-     * Invoked by react-router to notify this App that a Route is about to be
111
-     * rendered.
112
-     *
113
-     * @param {Route} route - The Route that is about to be rendered.
114
-     * @private
115
-     * @returns {void}
116
-     */
117
-    _onRouteEnter(route, ...args) {
118
-        // Notify the route that it is about to be entered.
119
-        const onEnter = route.onEnter;
120
-
121
-        if (typeof onEnter === 'function') {
122
-            onEnter(...args);
57
+        // Navigate to the specified Route.
58
+        const windowLocation = this._getWindowLocation();
59
+
60
+        if (windowLocation.pathname === path) {
61
+            // The browser is at the specified path already and what remains is
62
+            // to make this App instance aware of the route to be rendered at
63
+            // the current location.
64
+            super._navigate(route);
65
+        } else {
66
+            // The browser must go to the specified location. Once the specified
67
+            // location becomes current, the App will be made aware of the route
68
+            // to be rendered at it.
69
+            windowLocation.pathname = path;
123 70
         }
124
-
125
-        // XXX The following is mandatory. Otherwise, moving back & forward
126
-        // through the browser's history could leave this App on the Conference
127
-        // page without a room name.
128
-
129
-        // Our Router configuration (at the time of this writing) is such that
130
-        // each Route corresponds to a single URL. Hence, entering into a Route
131
-        // is like opening a URL.
132
-        this._openURL(window.location.toString());
133
-    }
134
-
135
-    /**
136
-     * Renders a specific Route (for the purposes of the Router of this App).
137
-     *
138
-     * @param {Object} route - The Route to render.
139
-     * @returns {ReactElement}
140
-     * @private
141
-     */
142
-    _renderRoute(route) {
143
-        const onEnter = (...args) => {
144
-            this._onRouteEnter(route, ...args);
145
-        };
146
-
147
-        return (
148
-            <Route
149
-                component = { route.component }
150
-                key = { route.component }
151
-                onEnter = { onEnter }
152
-                path = { route.path } />
153
-        );
154
-    }
155
-
156
-    /**
157
-     * Renders the Routes of the Router of this App.
158
-     *
159
-     * @returns {Array.<ReactElement>}
160
-     * @private
161
-     */
162
-    _renderRoutes() {
163
-        return RouteRegistry.getRoutes().map(this._renderRoute, this);
164
-    }
165
-
166
-    /**
167
-     * Create a ReactElement from the specified component and props on behalf of
168
-     * the associated Router.
169
-     *
170
-     * @param {Component} component - The component from which the ReactElement
171
-     * is to be created.
172
-     * @param {Object} props - The read-only React Component props with which
173
-     * the ReactElement is to be initialized.
174
-     * @private
175
-     * @returns {ReactElement}
176
-     */
177
-    _routerCreateElement(component, props) {
178
-        return this._createElement(component, props);
179 71
     }
180 72
 }

+ 2
- 2
react/features/app/functions.native.js Visa fil

@@ -107,8 +107,8 @@ function _urlStringToObject(url) {
107 107
         try {
108 108
             urlObj = new URL(url);
109 109
         } catch (ex) {
110
-            // The return value will signal the failure & the logged
111
-            // exception will provide the details to the developers.
110
+            // The return value will signal the failure & the logged exception
111
+            // will provide the details to the developers.
112 112
             console.log(`${url} seems to be not a valid URL, but it's OK`, ex);
113 113
         }
114 114
     }

+ 3
- 14
react/index.web.js Visa fil

@@ -2,8 +2,6 @@
2 2
 
3 3
 import React from 'react';
4 4
 import ReactDOM from 'react-dom';
5
-import { browserHistory } from 'react-router';
6
-import { routerMiddleware, routerReducer } from 'react-router-redux';
7 5
 import { compose, createStore } from 'redux';
8 6
 import Thunk from 'redux-thunk';
9 7
 
@@ -13,23 +11,14 @@ import { MiddlewareRegistry, ReducerRegistry } from './features/base/redux';
13 11
 
14 12
 const logger = require('jitsi-meet-logger').getLogger(__filename);
15 13
 
16
-// Create combined reducer from all reducers in registry + routerReducer from
17
-// 'react-router-redux' module (stores location updates from history).
18
-// @see https://github.com/reactjs/react-router-redux#routerreducer.
19
-const reducer = ReducerRegistry.combineReducers({
20
-    routing: routerReducer
21
-});
14
+// Create combined reducer from all reducers in registry.
15
+const reducer = ReducerRegistry.combineReducers();
22 16
 
23 17
 // Apply all registered middleware from the MiddlewareRegistry + additional
24 18
 // 3rd party middleware:
25 19
 // - Thunk - allows us to dispatch async actions easily. For more info
26 20
 // @see https://github.com/gaearon/redux-thunk.
27
-// - routerMiddleware - middleware from 'react-router-redux' module to track
28
-// changes in browser history inside Redux state. For more information
29
-// @see https://github.com/reactjs/react-router-redux.
30
-let middleware = MiddlewareRegistry.applyMiddleware(
31
-    Thunk,
32
-    routerMiddleware(browserHistory));
21
+let middleware = MiddlewareRegistry.applyMiddleware(Thunk);
33 22
 
34 23
 // Try to enable Redux DevTools Chrome extension in order to make it available
35 24
 // for the purposes of facilitating development.

Laddar…
Avbryt
Spara