Bläddra i källkod

Merge pull request #2946 from jitsi/fix-app-props-typeerror

[Android] Fix possible TypeError in multi-JitsiMeetView SDK consumers
j8
Zoltan Bettenbuk 7 år sedan
förälder
incheckning
b797b0b201
Inget konto är kopplat till bidragsgivarens mejladress

+ 28
- 0
react/features/app/functions.any.js Visa fil

1
+// @flow
2
+
3
+import { toState } from '../base/redux';
4
+
5
+/**
6
+ * Gets the value of a specific React {@code Component} prop of the currently
7
+ * mounted {@link App}.
8
+ *
9
+ * @param {Function|Object} stateful - The redux store or {@code getState}
10
+ * function.
11
+ * @param {string} propName - The name of the React {@code Component} prop of
12
+ * the currently mounted {@code App} to get.
13
+ * @returns {*} The value of the specified React {@code Compoennt} prop of the
14
+ * currently mounted {@code App}.
15
+ */
16
+export function getAppProp(stateful: Function | Object, propName: string) {
17
+    const state = toState(stateful)['features/app'];
18
+
19
+    if (state) {
20
+        const { app } = state;
21
+
22
+        if (app) {
23
+            return app.props[propName];
24
+        }
25
+    }
26
+
27
+    return undefined;
28
+}

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

2
 
2
 
3
 import { NativeModules } from 'react-native';
3
 import { NativeModules } from 'react-native';
4
 
4
 
5
+export * from './functions.any';
5
 export * from './getRouteToRender';
6
 export * from './getRouteToRender';
6
 
7
 
7
 /**
8
 /**

+ 3
- 1
react/features/app/functions.web.js Visa fil

1
-/* @flow */
1
+// @flow
2
 
2
 
3
 import { toState } from '../base/redux';
3
 import { toState } from '../base/redux';
4
 import { getDeepLinkingPage } from '../deep-linking';
4
 import { getDeepLinkingPage } from '../deep-linking';
49
     }
49
     }
50
 ];
50
 ];
51
 
51
 
52
+export * from './functions.any';
53
+
52
 /**
54
 /**
53
  * Determines which route is to be rendered in order to depict a specific redux
55
  * Determines which route is to be rendered in order to depict a specific redux
54
  * store.
56
  * store.

+ 3
- 5
react/features/invite/functions.js Visa fil

1
 // @flow
1
 // @flow
2
 
2
 
3
+import { getAppProp } from '../app';
3
 import { getLocalParticipant, PARTICIPANT_ROLE } from '../base/participants';
4
 import { getLocalParticipant, PARTICIPANT_ROLE } from '../base/participants';
4
 import { doGetJSON } from '../base/util';
5
 import { doGetJSON } from '../base/util';
5
 
6
 
282
         // XXX The mobile/react-native app is capable of disabling the
283
         // XXX The mobile/react-native app is capable of disabling the
283
         // adding/inviting of people in the current conference. Anyway, the
284
         // adding/inviting of people in the current conference. Anyway, the
284
         // Web/React app does not have that capability so default appropriately.
285
         // Web/React app does not have that capability so default appropriately.
285
-        const { app } = state['features/app'];
286
-        const addPeopleEnabled = app && app.props.addPeopleEnabled;
286
+        const addPeopleEnabled = getAppProp(state, 'addPeopleEnabled');
287
 
287
 
288
         return (
288
         return (
289
             (typeof addPeopleEnabled === 'undefined')
289
             (typeof addPeopleEnabled === 'undefined')
313
         // XXX The mobile/react-native app is capable of disabling of dial-out.
313
         // XXX The mobile/react-native app is capable of disabling of dial-out.
314
         // Anyway, the Web/React app does not have that capability so default
314
         // Anyway, the Web/React app does not have that capability so default
315
         // appropriately.
315
         // appropriately.
316
-        const { app } = state['features/app'];
317
-
318
-        dialOutEnabled = app && app.props.dialoOutEnabled;
316
+        dialOutEnabled = getAppProp(state, 'dialOutEnabled');
319
 
317
 
320
         return (
318
         return (
321
             (typeof dialOutEnabled === 'undefined') || Boolean(dialOutEnabled));
319
             (typeof dialOutEnabled === 'undefined') || Boolean(dialOutEnabled));

+ 6
- 13
react/features/invite/middleware.native.js Visa fil

4
 import { NativeEventEmitter, NativeModules } from 'react-native';
4
 import { NativeEventEmitter, NativeModules } from 'react-native';
5
 
5
 
6
 import { MiddlewareRegistry } from '../base/redux';
6
 import { MiddlewareRegistry } from '../base/redux';
7
-import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app';
7
+import { APP_WILL_MOUNT, APP_WILL_UNMOUNT, getAppProp } from '../app';
8
 
8
 
9
 import { invite } from './actions';
9
 import { invite } from './actions';
10
 import {
10
 import {
107
  * @private
107
  * @private
108
  * @returns {*} The value returned by {@code next(action)}.
108
  * @returns {*} The value returned by {@code next(action)}.
109
  */
109
  */
110
-function _beginAddPeople({ getState }, next, action) {
110
+function _beginAddPeople(store, next, action) {
111
     const result = next(action);
111
     const result = next(action);
112
 
112
 
113
     // The JavaScript App needs to provide uniquely identifying information to
113
     // The JavaScript App needs to provide uniquely identifying information to
114
     // the native Invite module so that the latter may match the former to the
114
     // the native Invite module so that the latter may match the former to the
115
     // native JitsiMeetView which hosts it.
115
     // native JitsiMeetView which hosts it.
116
-    const { app } = getState()['features/app'];
116
+    const externalAPIScope = getAppProp(store, 'externalAPIScope');
117
 
117
 
118
-    if (app) {
119
-        const { externalAPIScope } = app.props;
120
-
121
-        if (externalAPIScope) {
122
-            Invite.beginAddPeople(externalAPIScope);
123
-        }
124
-    }
118
+    externalAPIScope && Invite.beginAddPeople(externalAPIScope);
125
 
119
 
126
     return result;
120
     return result;
127
 }
121
 }
139
     // If there are multiple JitsiMeetView instances alive, they will all get
133
     // If there are multiple JitsiMeetView instances alive, they will all get
140
     // the event, since there is a single bridge, so make sure we don't act if
134
     // the event, since there is a single bridge, so make sure we don't act if
141
     // the event is not for us.
135
     // the event is not for us.
142
-    if (getState()['features/app'].app.props.externalAPIScope
143
-            !== externalAPIScope) {
136
+    if (getAppProp(getState, 'externalAPIScope') !== externalAPIScope) {
144
         return;
137
         return;
145
     }
138
     }
146
 
139
 
167
     // If there are multiple JitsiMeetView instances alive, they will all get
160
     // If there are multiple JitsiMeetView instances alive, they will all get
168
     // the event, since there is a single bridge, so make sure we don't act if
161
     // the event, since there is a single bridge, so make sure we don't act if
169
     // the event is not for us.
162
     // the event is not for us.
170
-    if (state['features/app'].app.props.externalAPIScope !== externalAPIScope) {
163
+    if (getAppProp(state, 'externalAPIScope') !== externalAPIScope) {
171
         return;
164
         return;
172
     }
165
     }
173
 
166
 

+ 6
- 13
react/features/mobile/external-api/middleware.js Visa fil

1
-/* @flow */
1
+// @flow
2
 
2
 
3
 import { NativeModules } from 'react-native';
3
 import { NativeModules } from 'react-native';
4
 
4
 
5
+import { getAppProp } from '../../app';
5
 import {
6
 import {
6
     CONFERENCE_FAILED,
7
     CONFERENCE_FAILED,
7
     CONFERENCE_JOINED,
8
     CONFERENCE_JOINED,
215
  * @private
216
  * @private
216
  * @returns {void}
217
  * @returns {void}
217
  */
218
  */
218
-function _sendEvent(
219
-        { getState }: { getState: Function },
220
-        name: string,
221
-        data: Object) {
219
+function _sendEvent(store: Object, name: string, data: Object) {
222
     // The JavaScript App needs to provide uniquely identifying information to
220
     // The JavaScript App needs to provide uniquely identifying information to
223
     // the native ExternalAPI module so that the latter may match the former to
221
     // the native ExternalAPI module so that the latter may match the former to
224
     // the native JitsiMeetView which hosts it.
222
     // the native JitsiMeetView which hosts it.
225
-    const { app } = getState()['features/app'];
223
+    const externalAPIScope = getAppProp(store, 'externalAPIScope');
226
 
224
 
227
-    if (app) {
228
-        const { externalAPIScope } = app.props;
229
-
230
-        if (externalAPIScope) {
231
-            NativeModules.ExternalAPI.sendEvent(name, data, externalAPIScope);
232
-        }
233
-    }
225
+    externalAPIScope
226
+        && NativeModules.ExternalAPI.sendEvent(name, data, externalAPIScope);
234
 }
227
 }
235
 
228
 
236
 /**
229
 /**

+ 2
- 4
react/features/mobile/picture-in-picture/actions.js Visa fil

2
 
2
 
3
 import { NativeModules } from 'react-native';
3
 import { NativeModules } from 'react-native';
4
 
4
 
5
+import { getAppProp } from '../../app';
5
 import { Platform } from '../../base/react';
6
 import { Platform } from '../../base/react';
6
 
7
 
7
 import { ENTER_PICTURE_IN_PICTURE } from './actionTypes';
8
 import { ENTER_PICTURE_IN_PICTURE } from './actionTypes';
18
  */
19
  */
19
 export function enterPictureInPicture() {
20
 export function enterPictureInPicture() {
20
     return (dispatch: Dispatch, getState: Function) => {
21
     return (dispatch: Dispatch, getState: Function) => {
21
-        const state = getState();
22
-        const { app } = state['features/app'];
23
-
24
         // XXX At the time of this writing this action can only be dispatched by
22
         // XXX At the time of this writing this action can only be dispatched by
25
         // the button which is on the conference view, which means that it's
23
         // the button which is on the conference view, which means that it's
26
         // fine to enter PiP mode.
24
         // fine to enter PiP mode.
27
-        if (app && app.props.pictureInPictureEnabled) {
25
+        if (getAppProp(getState, 'pictureInPictureEnabled')) {
28
             const { PictureInPicture } = NativeModules;
26
             const { PictureInPicture } = NativeModules;
29
             const p
27
             const p
30
                 = Platform.OS === 'android'
28
                 = Platform.OS === 'android'

+ 2
- 3
react/features/mobile/picture-in-picture/components/EnterPictureInPictureToolbarButton.js Visa fil

3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
 import { connect } from 'react-redux';
4
 import { connect } from 'react-redux';
5
 
5
 
6
+import { getAppProp } from '../../../app';
6
 import { ToolbarButton } from '../../../toolbox';
7
 import { ToolbarButton } from '../../../toolbox';
7
 
8
 
8
 import { enterPictureInPicture } from '../actions';
9
 import { enterPictureInPicture } from '../actions';
93
  * }}
94
  * }}
94
  */
95
  */
95
 function _mapStateToProps(state) {
96
 function _mapStateToProps(state) {
96
-    const { app } = state['features/app'];
97
-
98
     return {
97
     return {
99
 
98
 
100
         /**
99
         /**
104
          * @type {boolean}
103
          * @type {boolean}
105
          */
104
          */
106
         _pictureInPictureEnabled:
105
         _pictureInPictureEnabled:
107
-            Boolean(app && app.props.pictureInPictureEnabled)
106
+            Boolean(getAppProp(state, 'pictureInPictureEnabled'))
108
     };
107
     };
109
 }
108
 }
110
 
109
 

+ 10
- 12
react/features/welcome/functions.js Visa fil

1
-/* @flow */
1
+// @flow
2
 
2
 
3
+import { getAppProp } from '../app';
3
 import { toState } from '../base/redux';
4
 import { toState } from '../base/redux';
4
 
5
 
5
 declare var APP: Object;
6
 declare var APP: Object;
12
  * (e.g. programmatically via the Jitsi Meet SDK for Android and iOS). Not to be
13
  * (e.g. programmatically via the Jitsi Meet SDK for Android and iOS). Not to be
13
  * confused with {@link isWelcomePageUserEnabled}.
14
  * confused with {@link isWelcomePageUserEnabled}.
14
  *
15
  *
15
- * @param {Object|Function} stateOrGetState - The redux state or
16
- * {@link getState} function.
16
+ * @param {Function|Object} stateful - The redux state or {@link getState}
17
+ * function.
17
  * @returns {boolean} If the {@code WelcomePage} is enabled by the app, then
18
  * @returns {boolean} If the {@code WelcomePage} is enabled by the app, then
18
  * {@code true}; otherwise, {@code false}.
19
  * {@code true}; otherwise, {@code false}.
19
  */
20
  */
20
-export function isWelcomePageAppEnabled(stateOrGetState: Object | Function) {
21
+export function isWelcomePageAppEnabled(stateful: Function | Object) {
21
     let b;
22
     let b;
22
 
23
 
23
     if (navigator.product === 'ReactNative') {
24
     if (navigator.product === 'ReactNative') {
28
         // - Enabling/disabling the Welcome page on Web historically
29
         // - Enabling/disabling the Welcome page on Web historically
29
         // automatically redirects to a random room and that does not make sense
30
         // automatically redirects to a random room and that does not make sense
30
         // on mobile (right now).
31
         // on mobile (right now).
31
-        const { app } = toState(stateOrGetState)['features/app'];
32
-
33
-        b = Boolean(app && app.props.welcomePageEnabled);
32
+        b = Boolean(getAppProp(stateful, 'welcomePageEnabled'));
34
     } else {
33
     } else {
35
         b = true;
34
         b = true;
36
     }
35
     }
43
  * herself or through her deployment config(uration). Not to be confused with
42
  * herself or through her deployment config(uration). Not to be confused with
44
  * {@link isWelcomePageAppEnabled}.
43
  * {@link isWelcomePageAppEnabled}.
45
  *
44
  *
46
- * @param {Object|Function} stateOrGetState - The redux state or
47
- * {@link getState} function.
45
+ * @param {Function|Object} stateful - The redux state or {@link getState}
46
+ * function.
48
  * @returns {boolean} If the {@code WelcomePage} is enabled by the user, then
47
  * @returns {boolean} If the {@code WelcomePage} is enabled by the user, then
49
  * {@code true}; otherwise, {@code false}.
48
  * {@code true}; otherwise, {@code false}.
50
  */
49
  */
51
-export function isWelcomePageUserEnabled(stateOrGetState: Object | Function) {
50
+export function isWelcomePageUserEnabled(stateful: Function | Object) {
52
     return (
51
     return (
53
         typeof APP === 'undefined'
52
         typeof APP === 'undefined'
54
             ? true
53
             ? true
55
-            : toState(stateOrGetState)['features/base/config']
56
-                .enableWelcomePage);
54
+            : toState(stateful)['features/base/config'].enableWelcomePage);
57
 }
55
 }

Laddar…
Avbryt
Spara