Browse Source

(external_api) Add command for overwriting config values.

master
hmuresan 4 years ago
parent
commit
ab6790bdaa

+ 19
- 0
config.js View File

414
     // Base URL for a Gravatar-compatible service. Defaults to libravatar.
414
     // Base URL for a Gravatar-compatible service. Defaults to libravatar.
415
     // gravatarBaseURL: 'https://seccdn.libravatar.org/avatar/',
415
     // gravatarBaseURL: 'https://seccdn.libravatar.org/avatar/',
416
 
416
 
417
+    // Moved from interfaceConfig(TOOLBAR_BUTTONS).
418
+    // The name of the toolbar buttons to display in the toolbar, including the
419
+    // "More actions" menu. If present, the button will display. Exceptions are
420
+    // "livestreaming" and "recording" which also require being a moderator and
421
+    // some other values in config.js to be enabled. Also, the "profile" button will
422
+    // not display for users with a JWT.
423
+    // Notes:
424
+    // - it's impossible to choose which buttons go in the "More actions" menu
425
+    // - it's impossible to control the placement of buttons
426
+    // - 'desktop' controls the "Share your screen" button
427
+    // - if `toolbarButtons` is undefined, we fallback to enabling all buttons on the UI
428
+    // toolbarButtons: [
429
+    //    'microphone', 'camera', 'closedcaptions', 'desktop', 'embedmeeting', 'fullscreen',
430
+    //    'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
431
+    //    'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
432
+    //    'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
433
+    //    'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone', 'mute-video-everyone', 'security'
434
+    // ],
435
+
417
     // Stats
436
     // Stats
418
     //
437
     //
419
 
438
 

+ 9
- 16
interface_config.js View File

198
     TOOLBAR_ALWAYS_VISIBLE: false,
198
     TOOLBAR_ALWAYS_VISIBLE: false,
199
 
199
 
200
     /**
200
     /**
201
-     * The name of the toolbar buttons to display in the toolbar, including the
202
-     * "More actions" menu. If present, the button will display. Exceptions are
203
-     * "livestreaming" and "recording" which also require being a moderator and
204
-     * some values in config.js to be enabled. Also, the "profile" button will
205
-     * not display for users with a JWT.
206
-     * Notes:
207
-     * - it's impossible to choose which buttons go in the "More actions" menu
208
-     * - it's impossible to control the placement of buttons
209
-     * - 'desktop' controls the "Share your screen" button
201
+     * DEPRECATED!
202
+     * This config was moved to config.js as `toolbarButtons`.
210
      */
203
      */
211
-    TOOLBAR_BUTTONS: [
212
-        'microphone', 'camera', 'closedcaptions', 'desktop', 'embedmeeting', 'fullscreen',
213
-        'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
214
-        'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
215
-        'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
216
-        'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone', 'mute-video-everyone', 'security'
217
-    ],
204
+    // TOOLBAR_BUTTONS: [
205
+    //     'microphone', 'camera', 'closedcaptions', 'desktop', 'embedmeeting', 'fullscreen',
206
+    //     'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
207
+    //     'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
208
+    //     'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
209
+    //     'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone', 'mute-video-everyone', 'security'
210
+    // ],
218
 
211
 
219
     TOOLBAR_TIMEOUT: 4000,
212
     TOOLBAR_TIMEOUT: 4000,
220
 
213
 

+ 6
- 0
modules/API/API.js View File

12
     setPassword,
12
     setPassword,
13
     setSubject
13
     setSubject
14
 } from '../../react/features/base/conference';
14
 } from '../../react/features/base/conference';
15
+import { overwriteConfig, getWhitelistedJSON } from '../../react/features/base/config';
15
 import { parseJWTFromURLParams } from '../../react/features/base/jwt';
16
 import { parseJWTFromURLParams } from '../../react/features/base/jwt';
16
 import JitsiMeetJS, { JitsiRecordingConstants } from '../../react/features/base/lib-jitsi-meet';
17
 import JitsiMeetJS, { JitsiRecordingConstants } from '../../react/features/base/lib-jitsi-meet';
17
 import { MEDIA_TYPE } from '../../react/features/base/media';
18
 import { MEDIA_TYPE } from '../../react/features/base/media';
356
         },
357
         },
357
         'kick-participant': participantId => {
358
         'kick-participant': participantId => {
358
             APP.store.dispatch(kickParticipant(participantId));
359
             APP.store.dispatch(kickParticipant(participantId));
360
+        },
361
+        'overwrite-config': config => {
362
+            const whitelistedConfig = getWhitelistedJSON('config', config);
363
+
364
+            APP.store.dispatch(overwriteConfig(whitelistedConfig));
359
         }
365
         }
360
     };
366
     };
361
     transport.on('event', ({ data, name }) => {
367
     transport.on('event', ({ data, name }) => {

+ 1
- 0
modules/API/external/external_api.js View File

37
     intiatePrivateChat: 'initiate-private-chat',
37
     intiatePrivateChat: 'initiate-private-chat',
38
     kickParticipant: 'kick-participant',
38
     kickParticipant: 'kick-participant',
39
     muteEveryone: 'mute-everyone',
39
     muteEveryone: 'mute-everyone',
40
+    overwriteConfig: 'overwrite-config',
40
     password: 'password',
41
     password: 'password',
41
     pinParticipant: 'pin-participant',
42
     pinParticipant: 'pin-participant',
42
     resizeLargeVideo: 'resize-large-video',
43
     resizeLargeVideo: 'resize-large-video',

+ 11
- 0
react/features/base/config/actionTypes.js View File

48
  * }
48
  * }
49
  */
49
  */
50
 export const UPDATE_CONFIG = 'UPDATE_CONFIG';
50
 export const UPDATE_CONFIG = 'UPDATE_CONFIG';
51
+
52
+/**
53
+ * The redux action which overwrites configurations represented by the feature
54
+ * base/config. The passed on config values overwrite the current values for given props.
55
+ *
56
+ * {
57
+ *     type: OVERWRITE_CONFIG,
58
+ *     config: Object
59
+ * }
60
+ */
61
+export const OVERWRITE_CONFIG = 'OVERWRITE_CONFIG';

+ 23
- 1
react/features/base/config/actions.js View File

6
 import { addKnownDomains } from '../known-domains';
6
 import { addKnownDomains } from '../known-domains';
7
 import { parseURIString } from '../util';
7
 import { parseURIString } from '../util';
8
 
8
 
9
-import { CONFIG_WILL_LOAD, LOAD_CONFIG_ERROR, SET_CONFIG, UPDATE_CONFIG } from './actionTypes';
9
+import {
10
+    CONFIG_WILL_LOAD,
11
+    LOAD_CONFIG_ERROR,
12
+    SET_CONFIG,
13
+    UPDATE_CONFIG,
14
+    OVERWRITE_CONFIG
15
+} from './actionTypes';
10
 import { _CONFIG_STORE_PREFIX } from './constants';
16
 import { _CONFIG_STORE_PREFIX } from './constants';
11
 import { setConfigFromURLParams } from './functions';
17
 import { setConfigFromURLParams } from './functions';
12
 
18
 
67
     };
73
     };
68
 }
74
 }
69
 
75
 
76
+/**
77
+ * Overwrites some config values.
78
+ *
79
+ * @param {Object} config - The new options (to overwrite).
80
+ * @returns {{
81
+ *     type: OVERWRITE_CONFIG,
82
+ *     config: Object
83
+ * }}
84
+ */
85
+export function overwriteConfig(config: Object) {
86
+    return {
87
+        type: OVERWRITE_CONFIG,
88
+        config
89
+    };
90
+}
91
+
70
 /**
92
 /**
71
  * Sets the configuration represented by the feature base/config. The
93
  * Sets the configuration represented by the feature base/config. The
72
  * configuration is defined and consumed by the library lib-jitsi-meet but some
94
  * configuration is defined and consumed by the library lib-jitsi-meet but some

+ 1
- 0
react/features/base/config/configWhitelist.js View File

157
     'stereo',
157
     'stereo',
158
     'subject',
158
     'subject',
159
     'testing',
159
     'testing',
160
+    'toolbarButtons',
160
     'useHostPageLocalStorage',
161
     'useHostPageLocalStorage',
161
     'useTurnUdp',
162
     'useTurnUdp',
162
     'videoQuality.persist',
163
     'videoQuality.persist',

+ 14
- 0
react/features/base/config/constants.js View File

6
  * @type string
6
  * @type string
7
  */
7
  */
8
 export const _CONFIG_STORE_PREFIX = 'config.js';
8
 export const _CONFIG_STORE_PREFIX = 'config.js';
9
+
10
+/**
11
+ * The list of all possible UI buttons.
12
+ *
13
+ * @protected
14
+ * @type Array<string>
15
+ */
16
+export const TOOLBAR_BUTTONS = [
17
+    'microphone', 'camera', 'closedcaptions', 'desktop', 'embedmeeting', 'fullscreen',
18
+    'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
19
+    'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
20
+    'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
21
+    'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone', 'mute-video-everyone', 'security'
22
+];

+ 2
- 3
react/features/base/config/functions.any.js View File

82
         }
82
         }
83
         if (configObj) {
83
         if (configObj) {
84
             const configJSON
84
             const configJSON
85
-                = _getWhitelistedJSON(configName, json[configName]);
85
+                = getWhitelistedJSON(configName, json[configName]);
86
 
86
 
87
             if (!_.isEmpty(configJSON)) {
87
             if (!_.isEmpty(configJSON)) {
88
                 logger.info(
88
                 logger.info(
111
  * @param {string} configName - The config name, one of config,
111
  * @param {string} configName - The config name, one of config,
112
  * interfaceConfig, loggingConfig.
112
  * interfaceConfig, loggingConfig.
113
  * @param {Object} configJSON - The object with keys and values to override.
113
  * @param {Object} configJSON - The object with keys and values to override.
114
- * @private
115
  * @returns {Object} - The result object only with the keys
114
  * @returns {Object} - The result object only with the keys
116
  * that are whitelisted.
115
  * that are whitelisted.
117
  */
116
  */
118
-function _getWhitelistedJSON(configName, configJSON) {
117
+export function getWhitelistedJSON(configName: string, configJSON: Object): Object {
119
     if (configName === 'interfaceConfig') {
118
     if (configName === 'interfaceConfig') {
120
         return _.pick(configJSON, INTERFACE_CONFIG_WHITELIST);
119
         return _.pick(configJSON, INTERFACE_CONFIG_WHITELIST);
121
     } else if (configName === 'config') {
120
     } else if (configName === 'config') {

+ 14
- 0
react/features/base/config/functions.web.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
+import { TOOLBAR_BUTTONS } from './constants';
4
+
3
 export * from './functions.any';
5
 export * from './functions.any';
4
 
6
 
5
 /**
7
 /**
30
 export function getDialOutUrl(state: Object): string {
32
 export function getDialOutUrl(state: Object): string {
31
     return state['features/base/config'].guestDialOutUrl;
33
     return state['features/base/config'].guestDialOutUrl;
32
 }
34
 }
35
+
36
+/**
37
+ * Returns the list of enabled toolbar buttons.
38
+ *
39
+ * @param {Object} state - The redux state.
40
+ * @returns {Array<string>} - The list of enabled toolbar buttons.
41
+ */
42
+export function getToolbarButtons(state: Object): Array<string> {
43
+    const { toolbarButtons } = state['features/base/config'];
44
+
45
+    return Array.isArray(toolbarButtons) ? toolbarButtons : TOOLBAR_BUTTONS;
46
+}

+ 19
- 1
react/features/base/config/reducer.js View File

4
 
4
 
5
 import { equals, ReducerRegistry, set } from '../redux';
5
 import { equals, ReducerRegistry, set } from '../redux';
6
 
6
 
7
-import { UPDATE_CONFIG, CONFIG_WILL_LOAD, LOAD_CONFIG_ERROR, SET_CONFIG } from './actionTypes';
7
+import {
8
+    UPDATE_CONFIG,
9
+    CONFIG_WILL_LOAD,
10
+    LOAD_CONFIG_ERROR,
11
+    SET_CONFIG,
12
+    OVERWRITE_CONFIG
13
+} from './actionTypes';
8
 import { _cleanupConfig } from './functions';
14
 import { _cleanupConfig } from './functions';
9
 
15
 
16
+declare var interfaceConfig: Object;
17
+
10
 /**
18
 /**
11
  * The initial state of the feature base/config when executing in a
19
  * The initial state of the feature base/config when executing in a
12
  * non-React Native environment. The mandatory configuration to be passed to
20
  * non-React Native environment. The mandatory configuration to be passed to
88
 
96
 
89
     case SET_CONFIG:
97
     case SET_CONFIG:
90
         return _setConfig(state, action);
98
         return _setConfig(state, action);
99
+
100
+    case OVERWRITE_CONFIG:
101
+        return {
102
+            ...state,
103
+            ...action.config
104
+        };
91
     }
105
     }
92
 
106
 
93
     return state;
107
     return state;
197
         }
211
         }
198
     });
212
     });
199
 
213
 
214
+    if (typeof interfaceConfig === 'object' && Array.isArray(interfaceConfig.TOOLBAR_BUTTONS)) {
215
+        newValue.toolbarButtons = interfaceConfig.TOOLBAR_BUTTONS;
216
+    }
217
+
200
     return newValue;
218
     return newValue;
201
 }
219
 }
202
 
220
 

+ 1
- 1
react/features/conference/components/web/InviteMore.js View File

74
     const hide = interfaceConfig.HIDE_INVITE_MORE_HEADER;
74
     const hide = interfaceConfig.HIDE_INVITE_MORE_HEADER;
75
 
75
 
76
     return {
76
     return {
77
-        _visible: isToolboxVisible(state) && isButtonEnabled('invite') && isAlone && !hide
77
+        _visible: isToolboxVisible(state) && isButtonEnabled('invite', state) && isAlone && !hide
78
     };
78
     };
79
 }
79
 }
80
 
80
 

+ 10
- 2
react/features/filmstrip/components/web/Filmstrip.js View File

8
     createToolbarEvent,
8
     createToolbarEvent,
9
     sendAnalytics
9
     sendAnalytics
10
 } from '../../../analytics';
10
 } from '../../../analytics';
11
+import { getToolbarButtons } from '../../../base/config';
11
 import { translate } from '../../../base/i18n';
12
 import { translate } from '../../../base/i18n';
12
 import { Icon, IconMenuDown, IconMenuUp } from '../../../base/icons';
13
 import { Icon, IconMenuDown, IconMenuUp } from '../../../base/icons';
13
 import { connect } from '../../../base/redux';
14
 import { connect } from '../../../base/redux';
54
      */
55
      */
55
     _hideToolbar: boolean,
56
     _hideToolbar: boolean,
56
 
57
 
58
+    /**
59
+     * Whether the filmstrip button is enabled.
60
+     */
61
+    _isFilmstripButtonEnabled: boolean,
62
+
57
     /**
63
     /**
58
      * The number of rows in tile view.
64
      * The number of rows in tile view.
59
      */
65
      */
170
 
176
 
171
         let toolbar = null;
177
         let toolbar = null;
172
 
178
 
173
-        if (!this.props._hideToolbar && isButtonEnabled('filmstrip')) {
179
+        if (!this.props._hideToolbar && this.props._isFilmstripButtonEnabled) {
174
             toolbar = this._renderToggleButton();
180
             toolbar = this._renderToggleButton();
175
         }
181
         }
176
 
182
 
288
  */
294
  */
289
 function _mapStateToProps(state) {
295
 function _mapStateToProps(state) {
290
     const { iAmSipGateway } = state['features/base/config'];
296
     const { iAmSipGateway } = state['features/base/config'];
297
+    const toolbarButtons = getToolbarButtons(state);
291
     const { visible } = state['features/filmstrip'];
298
     const { visible } = state['features/filmstrip'];
292
     const reduceHeight
299
     const reduceHeight
293
-        = state['features/toolbox'].visible && interfaceConfig.TOOLBAR_BUTTONS.length;
300
+        = state['features/toolbox'].visible && toolbarButtons.length;
294
     const remoteVideosVisible = shouldRemoteVideosBeVisible(state);
301
     const remoteVideosVisible = shouldRemoteVideosBeVisible(state);
295
     const { isOpen: shiftRight } = state['features/chat'];
302
     const { isOpen: shiftRight } = state['features/chat'];
296
     const className = `${remoteVideosVisible ? '' : 'hide-videos'} ${
303
     const className = `${remoteVideosVisible ? '' : 'hide-videos'} ${
306
         _filmstripWidth: filmstripWidth,
313
         _filmstripWidth: filmstripWidth,
307
         _hideScrollbar: Boolean(iAmSipGateway),
314
         _hideScrollbar: Boolean(iAmSipGateway),
308
         _hideToolbar: Boolean(iAmSipGateway),
315
         _hideToolbar: Boolean(iAmSipGateway),
316
+        _isFilmstripButtonEnabled: isButtonEnabled('filmstrip', state),
309
         _rows: gridDimensions.rows,
317
         _rows: gridDimensions.rows,
310
         _videosClassName: videosClassName,
318
         _videosClassName: videosClassName,
311
         _visible: visible
319
         _visible: visible

+ 1
- 1
react/features/prejoin/components/Prejoin.js View File

420
     const name = getDisplayName(state);
420
     const name = getDisplayName(state);
421
     const showErrorOnJoin = isDisplayNameRequired(state) && !name;
421
     const showErrorOnJoin = isDisplayNameRequired(state) && !name;
422
     const { showJoinActions } = ownProps;
422
     const { showJoinActions } = ownProps;
423
-    const isInviteButtonEnabled = isButtonEnabled('invite');
423
+    const isInviteButtonEnabled = isButtonEnabled('invite', state);
424
 
424
 
425
     // Hide conference info when interfaceConfig is available and the invite button is disabled.
425
     // Hide conference info when interfaceConfig is available and the invite button is disabled.
426
     // In all other cases we want to preserve the behaviour and control the the conference info
426
     // In all other cases we want to preserve the behaviour and control the the conference info

+ 3
- 3
react/features/recording/components/LiveStream/web/LiveStreamButton.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
+import { getToolbarButtons } from '../../../../base/config';
3
 import { translate } from '../../../../base/i18n';
4
 import { translate } from '../../../../base/i18n';
4
 import { connect } from '../../../../base/redux';
5
 import { connect } from '../../../../base/redux';
5
 import AbstractLiveStreamButton, {
6
 import AbstractLiveStreamButton, {
7
     type Props
8
     type Props
8
 } from '../AbstractLiveStreamButton';
9
 } from '../AbstractLiveStreamButton';
9
 
10
 
10
-declare var interfaceConfig: Object;
11
-
12
 /**
11
 /**
13
  * Maps (parts of) the redux state to the associated props for the
12
  * Maps (parts of) the redux state to the associated props for the
14
  * {@code LiveStreamButton} component.
13
  * {@code LiveStreamButton} component.
25
  */
24
  */
26
 function _mapStateToProps(state: Object, ownProps: Props) {
25
 function _mapStateToProps(state: Object, ownProps: Props) {
27
     const abstractProps = _abstractMapStateToProps(state, ownProps);
26
     const abstractProps = _abstractMapStateToProps(state, ownProps);
27
+    const toolbarButtons = getToolbarButtons(state);
28
     let { visible } = ownProps;
28
     let { visible } = ownProps;
29
 
29
 
30
     if (typeof visible === 'undefined') {
30
     if (typeof visible === 'undefined') {
31
-        visible = interfaceConfig.TOOLBAR_BUTTONS.includes('livestreaming') && abstractProps.visible;
31
+        visible = toolbarButtons.includes('livestreaming') && abstractProps.visible;
32
     }
32
     }
33
 
33
 
34
     return {
34
     return {

+ 3
- 3
react/features/recording/components/Recording/web/RecordButton.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
+import { getToolbarButtons } from '../../../../base/config';
3
 import { translate } from '../../../../base/i18n';
4
 import { translate } from '../../../../base/i18n';
4
 import { connect } from '../../../../base/redux';
5
 import { connect } from '../../../../base/redux';
5
 import AbstractRecordButton, {
6
 import AbstractRecordButton, {
7
     type Props
8
     type Props
8
 } from '../AbstractRecordButton';
9
 } from '../AbstractRecordButton';
9
 
10
 
10
-declare var interfaceConfig: Object;
11
-
12
 /**
11
 /**
13
  * Maps (parts of) the redux state to the associated props for the
12
  * Maps (parts of) the redux state to the associated props for the
14
  * {@code RecordButton} component.
13
  * {@code RecordButton} component.
25
  */
24
  */
26
 export function _mapStateToProps(state: Object, ownProps: Props): Object {
25
 export function _mapStateToProps(state: Object, ownProps: Props): Object {
27
     const abstractProps = _abstractMapStateToProps(state, ownProps);
26
     const abstractProps = _abstractMapStateToProps(state, ownProps);
27
+    const toolbarButtons = getToolbarButtons(state);
28
     let { visible } = ownProps;
28
     let { visible } = ownProps;
29
 
29
 
30
     if (typeof visible === 'undefined') {
30
     if (typeof visible === 'undefined') {
31
-        visible = interfaceConfig.TOOLBAR_BUTTONS.includes('recording') && abstractProps.visible;
31
+        visible = toolbarButtons.includes('recording') && abstractProps.visible;
32
     }
32
     }
33
 
33
 
34
     return {
34
     return {

+ 1
- 1
react/features/remote-video-menu/components/web/PrivateMessageMenuButton.js View File

89
     return {
89
     return {
90
         ..._abstractMapStateToProps(state, ownProps),
90
         ..._abstractMapStateToProps(state, ownProps),
91
         _hidden: typeof interfaceConfig !== 'undefined'
91
         _hidden: typeof interfaceConfig !== 'undefined'
92
-            && (interfaceConfig.DISABLE_PRIVATE_MESSAGES || !isButtonEnabled('chat'))
92
+            && (interfaceConfig.DISABLE_PRIVATE_MESSAGES || !isButtonEnabled('chat', state))
93
     };
93
     };
94
 }
94
 }
95
 
95
 

+ 7
- 15
react/features/toolbox/components/web/Toolbox.js View File

8
     createToolbarEvent,
8
     createToolbarEvent,
9
     sendAnalytics
9
     sendAnalytics
10
 } from '../../../analytics';
10
 } from '../../../analytics';
11
+import { getToolbarButtons } from '../../../base/config';
11
 import { openDialog, toggleDialog } from '../../../base/dialog';
12
 import { openDialog, toggleDialog } from '../../../base/dialog';
12
 import { translate } from '../../../base/i18n';
13
 import { translate } from '../../../base/i18n';
13
 import {
14
 import {
29
     getParticipants,
30
     getParticipants,
30
     participantUpdated
31
     participantUpdated
31
 } from '../../../base/participants';
32
 } from '../../../base/participants';
32
-import { connect, equals } from '../../../base/redux';
33
+import { connect } from '../../../base/redux';
33
 import { OverflowMenuItem } from '../../../base/toolbox/components';
34
 import { OverflowMenuItem } from '../../../base/toolbox/components';
34
 import { getLocalVideoTrack, toggleScreensharing } from '../../../base/tracks';
35
 import { getLocalVideoTrack, toggleScreensharing } from '../../../base/tracks';
35
 import { isVpaasMeeting } from '../../../billing-counter/functions';
36
 import { isVpaasMeeting } from '../../../billing-counter/functions';
183
     _visible: boolean,
184
     _visible: boolean,
184
 
185
 
185
     /**
186
     /**
186
-     * Set with the buttons which this Toolbox should display.
187
+     * Array with the buttons which this Toolbox should display.
187
      */
188
      */
188
-    _visibleButtons: Set<string>,
189
+    _visibleButtons: Array<string>,
189
 
190
 
190
     /**
191
     /**
191
      * Invoked to active other features of the app.
192
      * Invoked to active other features of the app.
210
 };
211
 };
211
 
212
 
212
 declare var APP: Object;
213
 declare var APP: Object;
213
-declare var interfaceConfig: Object;
214
-
215
-// XXX: We are not currently using state here, but in the future, when
216
-// interfaceConfig is part of redux we will. This will have to be retrieved from the store.
217
-const visibleButtons = new Set(interfaceConfig.TOOLBAR_BUTTONS);
218
 
214
 
219
 /**
215
 /**
220
  * Implements the conference toolbox on React/Web.
216
  * Implements the conference toolbox on React/Web.
360
     render() {
356
     render() {
361
         const { _chatOpen, _visible, _visibleButtons } = this.props;
357
         const { _chatOpen, _visible, _visibleButtons } = this.props;
362
         const rootClassNames = `new-toolbox ${_visible ? 'visible' : ''} ${
358
         const rootClassNames = `new-toolbox ${_visible ? 'visible' : ''} ${
363
-            _visibleButtons.size ? '' : 'no-buttons'} ${_chatOpen ? 'shift-right' : ''}`;
359
+            _visibleButtons.length ? '' : 'no-buttons'} ${_chatOpen ? 'shift-right' : ''}`;
364
 
360
 
365
         return (
361
         return (
366
             <div
362
             <div
1280
      * @returns {boolean} True if the button should be displayed.
1276
      * @returns {boolean} True if the button should be displayed.
1281
      */
1277
      */
1282
     _shouldShowButton(buttonName) {
1278
     _shouldShowButton(buttonName) {
1283
-        return this.props._visibleButtons.has(buttonName);
1279
+        return this.props._visibleButtons.includes(buttonName);
1284
     }
1280
     }
1285
 }
1281
 }
1286
 
1282
 
1318
         desktopSharingDisabledTooltipKey = 'dialog.shareYourScreenDisabled';
1314
         desktopSharingDisabledTooltipKey = 'dialog.shareYourScreenDisabled';
1319
     }
1315
     }
1320
 
1316
 
1321
-    // NB: We compute the buttons again here because if URL parameters were used to
1322
-    // override them we'd miss it.
1323
-    const buttons = new Set(interfaceConfig.TOOLBAR_BUTTONS);
1324
-
1325
     return {
1317
     return {
1326
         _chatOpen: state['features/chat'].isOpen,
1318
         _chatOpen: state['features/chat'].isOpen,
1327
         _conference: conference,
1319
         _conference: conference,
1340
         _raisedHand: localParticipant.raisedHand,
1332
         _raisedHand: localParticipant.raisedHand,
1341
         _screensharing: localVideo && localVideo.videoType === 'desktop',
1333
         _screensharing: localVideo && localVideo.videoType === 'desktop',
1342
         _visible: isToolboxVisible(state),
1334
         _visible: isToolboxVisible(state),
1343
-        _visibleButtons: equals(visibleButtons, buttons) ? visibleButtons : buttons
1335
+        _visibleButtons: getToolbarButtons(state)
1344
     };
1336
     };
1345
 }
1337
 }
1346
 
1338
 

+ 6
- 10
react/features/toolbox/functions.web.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
+import { getToolbarButtons } from '../base/config';
3
 import { hasAvailableDevices } from '../base/devices';
4
 import { hasAvailableDevices } from '../base/devices';
4
 
5
 
5
-declare var interfaceConfig: Object;
6
-
7
 const WIDTH = {
6
 const WIDTH = {
8
     MEDIUM: 500,
7
     MEDIUM: 500,
9
     SMALL: 390,
8
     SMALL: 390,
53
  *
52
  *
54
  * @param {string} name - The name of the setting section as defined in
53
  * @param {string} name - The name of the setting section as defined in
55
  * interface_config.js.
54
  * interface_config.js.
55
+ * @param {Object} state - The redux state.
56
  * @returns {boolean|undefined} - True to indicate that the given toolbar button
56
  * @returns {boolean|undefined} - True to indicate that the given toolbar button
57
- * is enabled, false - otherwise. In cases where interfaceConfig is not available
58
- * undefined is returned.
57
+ * is enabled, false - otherwise.
59
  */
58
  */
60
-export function isButtonEnabled(name: string) {
61
-    if (typeof interfaceConfig === 'object' && Array.isArray(interfaceConfig.TOOLBAR_BUTTONS)) {
62
-        return interfaceConfig.TOOLBAR_BUTTONS.indexOf(name) !== -1;
63
-    }
59
+export function isButtonEnabled(name: string, state: Object) {
60
+    const toolbarButtons = getToolbarButtons(state);
64
 
61
 
65
-    return undefined;
62
+    return toolbarButtons.indexOf(name) !== -1;
66
 }
63
 }
67
 
64
 
68
-
69
 /**
65
 /**
70
  * Indicates if the toolbox is visible or not.
66
  * Indicates if the toolbox is visible or not.
71
  *
67
  *

Loading…
Cancel
Save