Browse Source

feat(config): Add config option for making display name read only

master
Vlad Piersec 4 years ago
parent
commit
fc6e8fd4b9

+ 4
- 0
config.js View File

476
     // When 'true', it shows an intermediate page before joining, where the user can configure their devices.
476
     // When 'true', it shows an intermediate page before joining, where the user can configure their devices.
477
     // prejoinPageEnabled: false,
477
     // prejoinPageEnabled: false,
478
 
478
 
479
+    // When 'true', the user cannot edit the display name.
480
+    // (Mainly useful when used in conjuction with the JWT so the JWT name becomes read only.)
481
+    // readOnlyName: false,
482
+
479
     // If etherpad integration is enabled, setting this to true will
483
     // If etherpad integration is enabled, setting this to true will
480
     // automatically open the etherpad when a participant joins.  This
484
     // automatically open the etherpad when a participant joins.  This
481
     // does not affect the mobile app since opening an etherpad
485
     // does not affect the mobile app since opening an etherpad

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

175
     'requireDisplayName',
175
     'requireDisplayName',
176
     'remoteVideoMenu',
176
     'remoteVideoMenu',
177
     'roomPasswordNumberOfDigits',
177
     'roomPasswordNumberOfDigits',
178
+    'readOnlyName',
178
     'replaceParticipant',
179
     'replaceParticipant',
179
     'resolution',
180
     'resolution',
180
     'startAudioMuted',
181
     'startAudioMuted',

+ 12
- 0
react/features/base/config/functions.any.js View File

152
     return configJSON;
152
     return configJSON;
153
 }
153
 }
154
 
154
 
155
+/**
156
+ * Selector for determining if the display name is read only.
157
+ *
158
+ * @param {Object} state - The state of the app.
159
+ * @returns {boolean}
160
+ */
161
+export function isNameReadOnly(state: Object): boolean {
162
+    return state['features/base/config'].disableProfile
163
+        || state['features/base/config'].readOnlyName;
164
+}
165
+
166
+
155
 /**
167
 /**
156
  * Restores a Jitsi Meet config.js from {@code localStorage} if it was
168
  * Restores a Jitsi Meet config.js from {@code localStorage} if it was
157
  * previously downloaded from a specific {@code baseURL} and stored with
169
  * previously downloaded from a specific {@code baseURL} and stored with

+ 6
- 0
react/features/base/premeeting/components/web/InputField.js View File

36
      */
36
      */
37
     placeHolder: string,
37
     placeHolder: string,
38
 
38
 
39
+    /**
40
+     * Whether the input is read only or not.
41
+     */
42
+    readOnly?: boolean,
43
+
39
     /**
44
     /**
40
      * The field type (e.g. text, password...etc).
45
      * The field type (e.g. text, password...etc).
41
      */
46
      */
126
                 onFocus = { this._onFocus }
131
                 onFocus = { this._onFocus }
127
                 onKeyDown = { this._onKeyDown }
132
                 onKeyDown = { this._onKeyDown }
128
                 placeholder = { this.props.placeHolder }
133
                 placeholder = { this.props.placeHolder }
134
+                readOnly = { this.props.readOnly }
129
                 type = { this.props.type }
135
                 type = { this.props.type }
130
                 value = { this.state.value } />
136
                 value = { this.state.value } />
131
         );
137
         );

+ 9
- 9
react/features/filmstrip/components/web/Thumbnail.js View File

5
 import { createScreenSharingIssueEvent, sendAnalytics } from '../../../analytics';
5
 import { createScreenSharingIssueEvent, sendAnalytics } from '../../../analytics';
6
 import { AudioLevelIndicator } from '../../../audio-level-indicator';
6
 import { AudioLevelIndicator } from '../../../audio-level-indicator';
7
 import { Avatar } from '../../../base/avatar';
7
 import { Avatar } from '../../../base/avatar';
8
+import { isNameReadOnly } from '../../../base/config';
8
 import { isMobileBrowser } from '../../../base/environment/utils';
9
 import { isMobileBrowser } from '../../../base/environment/utils';
9
 import JitsiMeetJS from '../../../base/lib-jitsi-meet/_';
10
 import JitsiMeetJS from '../../../base/lib-jitsi-meet/_';
10
 import { MEDIA_TYPE, VideoTrack } from '../../../base/media';
11
 import { MEDIA_TYPE, VideoTrack } from '../../../base/media';
73
  */
74
  */
74
 export type Props = {|
75
 export type Props = {|
75
 
76
 
77
+    /**
78
+     * If the display name is editable or not.
79
+     */
80
+    _allowEditing: boolean,
81
+
76
     /**
82
     /**
77
      * The audio track related to the participant.
83
      * The audio track related to the participant.
78
      */
84
      */
103
      */
109
      */
104
     _disableLocalVideoFlip: boolean,
110
     _disableLocalVideoFlip: boolean,
105
 
111
 
106
-    /**
107
-     * Indicates whether the profile functionality is disabled.
108
-     */
109
-    _disableProfile: boolean,
110
-
111
     /**
112
     /**
112
      * The display mode of the thumbnail.
113
      * The display mode of the thumbnail.
113
      */
114
      */
763
      */
764
      */
764
     _renderLocalParticipant() {
765
     _renderLocalParticipant() {
765
         const {
766
         const {
767
+            _allowEditing,
766
             _defaultLocalDisplayName,
768
             _defaultLocalDisplayName,
767
             _disableLocalVideoFlip,
769
             _disableLocalVideoFlip,
768
             _isMobile,
770
             _isMobile,
769
             _isMobilePortrait,
771
             _isMobilePortrait,
770
             _isScreenSharing,
772
             _isScreenSharing,
771
             _localFlipX,
773
             _localFlipX,
772
-            _disableProfile,
773
             _participant,
774
             _participant,
774
             _videoTrack
775
             _videoTrack
775
         } = this.props;
776
         } = this.props;
820
                     className = 'displayNameContainer'
821
                     className = 'displayNameContainer'
821
                     onClick = { onClick }>
822
                     onClick = { onClick }>
822
                     <DisplayName
823
                     <DisplayName
823
-                        allowEditing = { !_disableProfile }
824
+                        allowEditing = { _allowEditing }
824
                         displayNameSuffix = { _defaultLocalDisplayName }
825
                         displayNameSuffix = { _defaultLocalDisplayName }
825
                         elementID = 'localDisplayName'
826
                         elementID = 'localDisplayName'
826
                         participantID = { id } />
827
                         participantID = { id } />
1053
     const {
1054
     const {
1054
         startSilent,
1055
         startSilent,
1055
         disableLocalVideoFlip,
1056
         disableLocalVideoFlip,
1056
-        disableProfile,
1057
         iAmRecorder,
1057
         iAmRecorder,
1058
         iAmSipGateway
1058
         iAmSipGateway
1059
     } = state['features/base/config'];
1059
     } = state['features/base/config'];
1102
     }
1102
     }
1103
 
1103
 
1104
     return {
1104
     return {
1105
+        _allowEditing: !isNameReadOnly(state),
1105
         _audioTrack,
1106
         _audioTrack,
1106
         _connectionIndicatorAutoHideEnabled:
1107
         _connectionIndicatorAutoHideEnabled:
1107
         Boolean(state['features/base/config'].connectionIndicators?.autoHide ?? true),
1108
         Boolean(state['features/base/config'].connectionIndicators?.autoHide ?? true),
1110
         _currentLayout,
1111
         _currentLayout,
1111
         _defaultLocalDisplayName: interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME,
1112
         _defaultLocalDisplayName: interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME,
1112
         _disableLocalVideoFlip: Boolean(disableLocalVideoFlip),
1113
         _disableLocalVideoFlip: Boolean(disableLocalVideoFlip),
1113
-        _disableProfile: disableProfile,
1114
         _isHidden: isLocal && iAmRecorder && !iAmSipGateway,
1114
         _isHidden: isLocal && iAmRecorder && !iAmSipGateway,
1115
         _isAudioOnly: Boolean(state['features/base/audio-only'].enabled),
1115
         _isAudioOnly: Boolean(state['features/base/audio-only'].enabled),
1116
         _isCurrentlyOnLargeVideo: state['features/large-video']?.participantId === id,
1116
         _isCurrentlyOnLargeVideo: state['features/large-video']?.participantId === id,

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

4
 import React, { Component } from 'react';
4
 import React, { Component } from 'react';
5
 
5
 
6
 import { getRoomName } from '../../base/conference';
6
 import { getRoomName } from '../../base/conference';
7
+import { isNameReadOnly } from '../../base/config';
7
 import { translate } from '../../base/i18n';
8
 import { translate } from '../../base/i18n';
8
 import { Icon, IconArrowDown, IconArrowUp, IconPhone, IconVolumeOff } from '../../base/icons';
9
 import { Icon, IconArrowDown, IconArrowUp, IconPhone, IconVolumeOff } from '../../base/icons';
9
 import { isVideoMutedByUser } from '../../base/media';
10
 import { isVideoMutedByUser } from '../../base/media';
57
      */
58
      */
58
     updateSettings: Function,
59
     updateSettings: Function,
59
 
60
 
61
+    /**
62
+     * Whether the name input should be read only or not.
63
+     */
64
+    readOnlyName: boolean,
65
+
60
     /**
66
     /**
61
      * The name of the meeting that is about to be joined.
67
      * The name of the meeting that is about to be joined.
62
      */
68
      */
283
             joinConference,
289
             joinConference,
284
             joinConferenceWithoutAudio,
290
             joinConferenceWithoutAudio,
285
             name,
291
             name,
292
+            readOnlyName,
286
             showCameraPreview,
293
             showCameraPreview,
287
             showDialog,
294
             showDialog,
288
             t,
295
             t,
310
                         onChange = { _setName }
317
                         onChange = { _setName }
311
                         onSubmit = { joinConference }
318
                         onSubmit = { joinConference }
312
                         placeHolder = { t('dialog.enterDisplayName') }
319
                         placeHolder = { t('dialog.enterDisplayName') }
320
+                        readOnly = { readOnlyName }
313
                         value = { name } />
321
                         value = { name } />
314
 
322
 
315
                     {showError && <div
323
                     {showError && <div
393
         showDialog: isJoinByPhoneDialogVisible(state),
401
         showDialog: isJoinByPhoneDialogVisible(state),
394
         showErrorOnJoin,
402
         showErrorOnJoin,
395
         hasJoinByPhoneButton: isJoinByPhoneButtonVisible(state),
403
         hasJoinByPhoneButton: isJoinByPhoneButtonVisible(state),
404
+        readOnlyName: isNameReadOnly(state),
396
         showCameraPreview: !isVideoMutedByUser(state),
405
         showCameraPreview: !isVideoMutedByUser(state),
397
         videoTrack: getLocalJitsiVideoTrack(state)
406
         videoTrack: getLocalJitsiVideoTrack(state)
398
     };
407
     };

+ 7
- 0
react/features/settings/components/web/ProfileTab.js View File

42
      */
42
      */
43
     email: string,
43
     email: string,
44
 
44
 
45
+    /**
46
+     * If the display name is read only.
47
+     */
48
+    readOnlyName: boolean,
49
+
45
     /**
50
     /**
46
      * Invoked to obtain translated strings.
51
      * Invoked to obtain translated strings.
47
      */
52
      */
111
             authEnabled,
116
             authEnabled,
112
             displayName,
117
             displayName,
113
             email,
118
             email,
119
+            readOnlyName,
114
             t
120
             t
115
         } = this.props;
121
         } = this.props;
116
 
122
 
122
                             autoComplete = 'name'
128
                             autoComplete = 'name'
123
                             compact = { true }
129
                             compact = { true }
124
                             id = 'setDisplayName'
130
                             id = 'setDisplayName'
131
+                            isReadOnly = { readOnlyName }
125
                             label = { t('profile.setDisplayNameLabel') }
132
                             label = { t('profile.setDisplayNameLabel') }
126
                             onChange = { this._onDisplayNameChange }
133
                             onChange = { this._onDisplayNameChange }
127
                             placeholder = { t('settings.name') }
134
                             placeholder = { t('settings.name') }

+ 3
- 1
react/features/settings/functions.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
+import { isNameReadOnly } from '../base/config';
3
 import { SERVER_URL_CHANGE_ENABLED, getFeatureFlag } from '../base/flags';
4
 import { SERVER_URL_CHANGE_ENABLED, getFeatureFlag } from '../base/flags';
4
 import { i18next, DEFAULT_LANGUAGE, LANGUAGES } from '../base/i18n';
5
 import { i18next, DEFAULT_LANGUAGE, LANGUAGES } from '../base/i18n';
5
 import { createLocalTrack } from '../base/lib-jitsi-meet/functions';
6
 import { createLocalTrack } from '../base/lib-jitsi-meet/functions';
153
         authEnabled: Boolean(conference && authEnabled),
154
         authEnabled: Boolean(conference && authEnabled),
154
         authLogin,
155
         authLogin,
155
         displayName: localParticipant.name,
156
         displayName: localParticipant.name,
156
-        email: localParticipant.email
157
+        email: localParticipant.email,
158
+        readOnlyName: isNameReadOnly(state)
157
     };
159
     };
158
 }
160
 }
159
 
161
 

Loading…
Cancel
Save