Sfoglia il codice sorgente

Remove duplication

The files react/index.native.js and react/index.web.js ended up having
very similar source code related to initializing the Redux store. Remove
the duplication.

Additionally, I always wanted the App React Component to be consumed
without the need to provide a Redux store to it.
j8
Lyubomir Marinov 8 anni fa
parent
commit
49b3b49f3e

+ 112
- 6
react/features/app/components/AbstractApp.js Vedi File

1
 import React, { Component } from 'react';
1
 import React, { Component } from 'react';
2
 import { Provider } from 'react-redux';
2
 import { Provider } from 'react-redux';
3
+import { compose, createStore } from 'redux';
4
+import Thunk from 'redux-thunk';
3
 
5
 
4
 import { RouteRegistry } from '../../base/navigator';
6
 import { RouteRegistry } from '../../base/navigator';
5
 import {
7
 import {
6
     localParticipantJoined,
8
     localParticipantJoined,
7
     localParticipantLeft
9
     localParticipantLeft
8
 } from '../../base/participants';
10
 } from '../../base/participants';
11
+import { MiddlewareRegistry, ReducerRegistry } from '../../base/redux';
9
 
12
 
10
 import {
13
 import {
11
     appNavigate,
14
     appNavigate,
45
 
48
 
46
         this.state = {
49
         this.state = {
47
             /**
50
             /**
48
-             * The Route rendered by this App.
51
+             * The Route rendered by this AbstractApp.
49
              *
52
              *
50
              * @type {Route}
53
              * @type {Route}
51
              */
54
              */
52
-            route: undefined
55
+            route: undefined,
56
+
57
+            /**
58
+             * The Redux store used by this AbstractApp.
59
+             *
60
+             * @type {Store}
61
+             */
62
+            store: this._maybeCreateStore(props)
53
         };
63
         };
54
     }
64
     }
55
 
65
 
60
      * @inheritdoc
70
      * @inheritdoc
61
      */
71
      */
62
     componentWillMount() {
72
     componentWillMount() {
63
-        const dispatch = this.props.store.dispatch;
73
+        const dispatch = this._getStore().dispatch;
64
 
74
 
65
         dispatch(appWillMount(this));
75
         dispatch(appWillMount(this));
66
 
76
 
69
         this._openURL(this._getDefaultURL());
79
         this._openURL(this._getDefaultURL());
70
     }
80
     }
71
 
81
 
82
+    /**
83
+     * Notifies this mounted React Component that it will receive new props.
84
+     * Makes sure that this AbstractApp has a Redux store to use.
85
+     *
86
+     * @inheritdoc
87
+     * @param {Object} nextProps - The read-only React Component props that this
88
+     * instance will receive.
89
+     * @returns {void}
90
+     */
91
+    componentWillReceiveProps(nextProps) {
92
+        // The consumer of this AbstractApp did not provide a Redux store.
93
+        if (typeof nextProps.store === 'undefined'
94
+
95
+                // The consumer of this AbstractApp  did provide a Redux store
96
+                // before. Which means that the consumer changed their mind. In
97
+                // such a case this instance should create its own internal
98
+                // Redux store. If the consumer did not provide a Redux store
99
+                // before, then this instance is using its own internal Redux
100
+                // store already.
101
+                && typeof this.props.store !== 'undefined') {
102
+            this.setState({
103
+                store: this._maybeCreateStore(nextProps)
104
+            });
105
+        }
106
+    }
107
+
72
     /**
108
     /**
73
      * Dispose lib-jitsi-meet and remove local participant when component is
109
      * Dispose lib-jitsi-meet and remove local participant when component is
74
      * going to be unmounted.
110
      * going to be unmounted.
76
      * @inheritdoc
112
      * @inheritdoc
77
      */
113
      */
78
     componentWillUnmount() {
114
     componentWillUnmount() {
79
-        const dispatch = this.props.store.dispatch;
115
+        const dispatch = this._getStore().dispatch;
80
 
116
 
81
         dispatch(localParticipantLeft());
117
         dispatch(localParticipantLeft());
82
 
118
 
94
 
130
 
95
         if (route) {
131
         if (route) {
96
             return (
132
             return (
97
-                <Provider store = { this.props.store }>
133
+                <Provider store = { this._getStore() }>
98
                     {
134
                     {
99
                         this._createElement(route.component)
135
                         this._createElement(route.component)
100
                     }
136
                     }
142
         return React.createElement(component, { ...thisProps, ...props });
178
         return React.createElement(component, { ...thisProps, ...props });
143
     }
179
     }
144
 
180
 
181
+    /**
182
+     * Initializes a new Redux store instance suitable for use by
183
+     * this AbstractApp.
184
+     *
185
+     * @private
186
+     * @returns {Store} - A new Redux store instance suitable for use by
187
+     * this AbstractApp.
188
+     */
189
+    _createStore() {
190
+        // Create combined reducer from all reducers in ReducerRegistry.
191
+        const reducer = ReducerRegistry.combineReducers();
192
+
193
+        // Apply all registered middleware from the MiddlewareRegistry and
194
+        // additional 3rd party middleware:
195
+        // - Thunk - allows us to dispatch async actions easily. For more info
196
+        // @see https://github.com/gaearon/redux-thunk.
197
+        let middleware = MiddlewareRegistry.applyMiddleware(Thunk);
198
+
199
+        // Try to enable Redux DevTools Chrome extension in order to make it
200
+        // available for the purposes of facilitating development.
201
+        let devToolsExtension;
202
+
203
+        if (typeof window === 'object'
204
+                && (devToolsExtension = window.devToolsExtension)) {
205
+            middleware = compose(middleware, devToolsExtension());
206
+        }
207
+
208
+        return createStore(reducer, middleware);
209
+    }
210
+
145
     /**
211
     /**
146
      * Gets the default URL to be opened when this App mounts.
212
      * Gets the default URL to be opened when this App mounts.
147
      *
213
      *
189
         return 'https://meet.jit.si';
255
         return 'https://meet.jit.si';
190
     }
256
     }
191
 
257
 
258
+    /**
259
+     * Gets the Redux store used by this AbstractApp.
260
+     *
261
+     * @protected
262
+     * @returns {Store} - The Redux store used by this AbstractApp.
263
+     */
264
+    _getStore() {
265
+        let store = this.state.store;
266
+
267
+        if (typeof store === 'undefined') {
268
+            store = this.props.store;
269
+        }
270
+
271
+        return store;
272
+    }
273
+
192
     /**
274
     /**
193
      * Gets a Location object from the window with information about the current
275
      * Gets a Location object from the window with information about the current
194
      * location of the document. Explicitly defined to allow extenders to
276
      * location of the document. Explicitly defined to allow extenders to
204
         return undefined;
286
         return undefined;
205
     }
287
     }
206
 
288
 
289
+    /**
290
+     * Creates a Redux store to be used by this AbstractApp if such as store is
291
+     * not defined by the consumer of this AbstractApp through its
292
+     * read-only React Component props.
293
+     *
294
+     * @param {Object} props - The read-only React Component props that will
295
+     * eventually be received by this AbstractApp.
296
+     * @private
297
+     * @returns {Store} - The Redux store to be used by this AbstractApp.
298
+     */
299
+    _maybeCreateStore(props) {
300
+        // The application Jitsi Meet is architected with Redux. However, I do
301
+        // not want consumers of the App React Component to be forced into
302
+        // dealing with Redux. If the consumer did not provide an external Redux
303
+        // store, utilize an internal Redux store.
304
+        let store = props.store;
305
+
306
+        if (typeof store === 'undefined') {
307
+            store = this._createStore();
308
+        }
309
+
310
+        return store;
311
+    }
312
+
207
     /**
313
     /**
208
      * Navigates to a specific Route.
314
      * Navigates to a specific Route.
209
      *
315
      *
269
      * @returns {void}
375
      * @returns {void}
270
      */
376
      */
271
     _openURL(url) {
377
     _openURL(url) {
272
-        this.props.store.dispatch(appNavigate(url));
378
+        this._getStore().dispatch(appNavigate(url));
273
     }
379
     }
274
 }
380
 }

+ 2
- 2
react/features/app/components/App.web.js Vedi File

22
     componentWillMount(...args) {
22
     componentWillMount(...args) {
23
         super.componentWillMount(...args);
23
         super.componentWillMount(...args);
24
 
24
 
25
-        this.props.store.dispatch(appInit());
25
+        this._getStore().dispatch(appInit());
26
     }
26
     }
27
 
27
 
28
     /**
28
     /**
44
      */
44
      */
45
     _navigate(route) {
45
     _navigate(route) {
46
         let path = route.path;
46
         let path = route.path;
47
-        const store = this.props.store;
47
+        const store = this._getStore();
48
 
48
 
49
         // The syntax :room bellow is defined by react-router. It "matches a URL
49
         // The syntax :room bellow is defined by react-router. It "matches a URL
50
         // segment up to the next /, ?, or #. The matched string is called a
50
         // segment up to the next /, ?, or #. The matched string is called a

+ 0
- 19
react/index.native.js Vedi File

1
 import React, { Component } from 'react';
1
 import React, { Component } from 'react';
2
 import { AppRegistry, Linking } from 'react-native';
2
 import { AppRegistry, Linking } from 'react-native';
3
-import { createStore } from 'redux';
4
-import Thunk from 'redux-thunk';
5
 
3
 
6
 import config from './config';
4
 import config from './config';
7
 import { App } from './features/app';
5
 import { App } from './features/app';
8
-import {
9
-    MiddlewareRegistry,
10
-    ReducerRegistry
11
-} from './features/base/redux';
12
-
13
-// Create combined reducer from all reducers in registry.
14
-const reducer = ReducerRegistry.combineReducers();
15
-
16
-// Apply all registered middleware from the MiddlewareRegistry + additional
17
-// 3rd party middleware:
18
-// - Thunk - allows us to dispatch async actions easily. For more info
19
-// @see https://github.com/gaearon/redux-thunk.
20
-const middleware = MiddlewareRegistry.applyMiddleware(Thunk);
21
-
22
-// Create Redux store with our reducer and middleware.
23
-const store = createStore(reducer, middleware);
24
 
6
 
25
 /**
7
 /**
26
  * React Native doesn't support specifying props to the main/root component (in
8
  * React Native doesn't support specifying props to the main/root component (in
83
         return (
65
         return (
84
             <App
66
             <App
85
                 config = { config }
67
                 config = { config }
86
-                store = { store }
87
                 url = { this.state.url } />
68
                 url = { this.state.url } />
88
         );
69
         );
89
     }
70
     }

+ 1
- 27
react/index.web.js Vedi File

2
 
2
 
3
 import React from 'react';
3
 import React from 'react';
4
 import ReactDOM from 'react-dom';
4
 import ReactDOM from 'react-dom';
5
-import { compose, createStore } from 'redux';
6
-import Thunk from 'redux-thunk';
7
 
5
 
8
 import config from './config';
6
 import config from './config';
9
 import { App } from './features/app';
7
 import { App } from './features/app';
10
-import { MiddlewareRegistry, ReducerRegistry } from './features/base/redux';
11
 
8
 
12
 const logger = require('jitsi-meet-logger').getLogger(__filename);
9
 const logger = require('jitsi-meet-logger').getLogger(__filename);
13
 
10
 
14
-// Create combined reducer from all reducers in registry.
15
-const reducer = ReducerRegistry.combineReducers();
16
-
17
-// Apply all registered middleware from the MiddlewareRegistry + additional
18
-// 3rd party middleware:
19
-// - Thunk - allows us to dispatch async actions easily. For more info
20
-// @see https://github.com/gaearon/redux-thunk.
21
-let middleware = MiddlewareRegistry.applyMiddleware(Thunk);
22
-
23
-// Try to enable Redux DevTools Chrome extension in order to make it available
24
-// for the purposes of facilitating development.
25
-let devToolsExtension;
26
-
27
-if (typeof window === 'object'
28
-        && (devToolsExtension = window.devToolsExtension)) {
29
-    middleware = compose(middleware, devToolsExtension());
30
-}
31
-
32
-// Create Redux store with our reducer and middleware.
33
-const store = createStore(reducer, middleware);
34
-
35
 /**
11
 /**
36
  * Renders the app when the DOM tree has been loaded.
12
  * Renders the app when the DOM tree has been loaded.
37
  */
13
  */
43
 
19
 
44
     // Render the main Component.
20
     // Render the main Component.
45
     ReactDOM.render(
21
     ReactDOM.render(
46
-        <App
47
-            config = { config }
48
-            store = { store } />,
22
+        <App config = { config } />,
49
         document.getElementById('react'));
23
         document.getElementById('react'));
50
 });
24
 });
51
 
25
 

Loading…
Annulla
Salva