Browse Source

feat: override email, display name and avatar on mobile

Will override email, display name and avatar URL with the values
provided in 'context.user' structure of the JWT token.

Settings will no longer be used to retrieve local display name,
email and avatar URL. Now those values will be obtained from
the /features/base/participants Redux state.

fix(jwt/middleware): use const for default name

fix: wrong default display name on web

ref(base/participants): remove getDisplayName functions

ref(jwt): do not accept unknown user fields
master
paweldomas 7 years ago
parent
commit
8a4e6a7ec0

+ 27
- 42
conference.js View File

30
     toggleAudioOnly,
30
     toggleAudioOnly,
31
     EMAIL_COMMAND,
31
     EMAIL_COMMAND,
32
     lockStateChanged,
32
     lockStateChanged,
33
-    p2pStatusChanged
33
+    p2pStatusChanged,
34
+    setLocalParticipantData
34
 } from './react/features/base/conference';
35
 } from './react/features/base/conference';
35
 import { updateDeviceList } from './react/features/base/devices';
36
 import { updateDeviceList } from './react/features/base/devices';
36
 import {
37
 import {
55
 } from './react/features/base/media';
56
 } from './react/features/base/media';
56
 import {
57
 import {
57
     dominantSpeakerChanged,
58
     dominantSpeakerChanged,
59
+    getLocalParticipant,
60
+    getParticipantById,
58
     localParticipantConnectionStatusChanged,
61
     localParticipantConnectionStatusChanged,
59
     localParticipantRoleChanged,
62
     localParticipantRoleChanged,
60
     MAX_DISPLAY_NAME_LENGTH,
63
     MAX_DISPLAY_NAME_LENGTH,
143
     room.sendCommand(command, {value: value});
146
     room.sendCommand(command, {value: value});
144
 }
147
 }
145
 
148
 
146
-/**
147
- * Sets up initially the properties of the local participant - email, avatarID,
148
- * avatarURL, displayName, etc.
149
- */
150
-function _setupLocalParticipantProperties() {
151
-    const email = APP.settings.getEmail();
152
-    email && sendData(commands.EMAIL, email);
153
-
154
-    const avatarUrl = APP.settings.getAvatarUrl();
155
-    avatarUrl && sendData(commands.AVATAR_URL, avatarUrl);
156
-
157
-    if (!email && !avatarUrl) {
158
-        sendData(commands.AVATAR_ID, APP.settings.getAvatarId());
159
-    }
160
-
161
-    let nick = APP.settings.getDisplayName();
162
-    if (config.useNicks && !nick) {
163
-        nick = APP.UI.askForNickname();
164
-        APP.settings.setDisplayName(nick);
165
-    }
166
-    nick && room.setDisplayName(nick);
167
-}
168
-
169
 /**
149
 /**
170
  * Get user nickname by user id.
150
  * Get user nickname by user id.
171
  * @param {string} id user id
151
  * @param {string} id user id
172
  * @returns {string?} user nickname or undefined if user is unknown.
152
  * @returns {string?} user nickname or undefined if user is unknown.
173
  */
153
  */
174
 function getDisplayName(id) {
154
 function getDisplayName(id) {
175
-    if (APP.conference.isLocalId(id)) {
176
-        return APP.settings.getDisplayName();
177
-    }
155
+    const participant = getParticipantById(APP.store.getState(), id);
178
 
156
 
179
-    let participant = room.getParticipantById(id);
180
-    if (participant && participant.getDisplayName()) {
181
-        return participant.getDisplayName();
182
-    }
157
+    return participant && participant.name;
183
 }
158
 }
184
 
159
 
185
 /**
160
 /**
989
     isConnectionInterrupted() {
964
     isConnectionInterrupted() {
990
         return this._room.isConnectionInterrupted();
965
         return this._room.isConnectionInterrupted();
991
     },
966
     },
967
+    /**
968
+     * Obtains the local display name.
969
+     * @returns {string|undefined}
970
+     */
971
+    getLocalDisplayName() {
972
+        return getDisplayName(this.getMyUserId());
973
+    },
992
     /**
974
     /**
993
      * Finds JitsiParticipant for given id.
975
      * Finds JitsiParticipant for given id.
994
      *
976
      *
1162
         this._setLocalAudioVideoStreams(localTracks);
1144
         this._setLocalAudioVideoStreams(localTracks);
1163
         this._room = room; // FIXME do not use this
1145
         this._room = room; // FIXME do not use this
1164
 
1146
 
1165
-        _setupLocalParticipantProperties();
1147
+        setLocalParticipantData(room, APP.store.getState());
1166
 
1148
 
1167
         this._setupListeners();
1149
         this._setupListeners();
1168
     },
1150
     },
2420
      * @param email {string} the new email
2402
      * @param email {string} the new email
2421
      */
2403
      */
2422
     changeLocalEmail(email = '') {
2404
     changeLocalEmail(email = '') {
2405
+        const localParticipant = getLocalParticipant(APP.store.getState());
2406
+
2423
         email = String(email).trim();
2407
         email = String(email).trim();
2424
 
2408
 
2425
-        if (email === APP.settings.getEmail()) {
2409
+        if (email === localParticipant.email) {
2426
             return;
2410
             return;
2427
         }
2411
         }
2428
 
2412
 
2429
-        const localId = room ? room.myUserId() : undefined;
2413
+        const localId = localParticipant.id;
2430
 
2414
 
2431
         APP.store.dispatch(participantUpdated({
2415
         APP.store.dispatch(participantUpdated({
2432
             id: localId,
2416
             id: localId,
2444
      * @param url {string} the new url
2428
      * @param url {string} the new url
2445
      */
2429
      */
2446
     changeLocalAvatarUrl(url = '') {
2430
     changeLocalAvatarUrl(url = '') {
2431
+        const { avatarURL, id } = getLocalParticipant(APP.store.getState());
2432
+
2447
         url = String(url).trim();
2433
         url = String(url).trim();
2448
 
2434
 
2449
-        if (url === APP.settings.getAvatarUrl()) {
2435
+        if (url === avatarURL) {
2450
             return;
2436
             return;
2451
         }
2437
         }
2452
 
2438
 
2453
-        const localId = room ? room.myUserId() : undefined;
2454
-
2455
         APP.store.dispatch(participantUpdated({
2439
         APP.store.dispatch(participantUpdated({
2456
-            id: localId,
2440
+            id,
2457
             local: true,
2441
             local: true,
2458
             avatarURL: url
2442
             avatarURL: url
2459
         }));
2443
         }));
2460
 
2444
 
2461
         APP.settings.setAvatarUrl(url);
2445
         APP.settings.setAvatarUrl(url);
2462
-        APP.UI.setUserAvatarUrl(localId, url);
2446
+        APP.UI.setUserAvatarUrl(id, url);
2463
         sendData(commands.AVATAR_URL, url);
2447
         sendData(commands.AVATAR_URL, url);
2464
     },
2448
     },
2465
 
2449
 
2501
     changeLocalDisplayName(nickname = '') {
2485
     changeLocalDisplayName(nickname = '') {
2502
         const formattedNickname
2486
         const formattedNickname
2503
             = nickname.trim().substr(0, MAX_DISPLAY_NAME_LENGTH);
2487
             = nickname.trim().substr(0, MAX_DISPLAY_NAME_LENGTH);
2488
+        const { id, name } = getLocalParticipant(APP.store.getState());
2504
 
2489
 
2505
-        if (formattedNickname === APP.settings.getDisplayName()) {
2490
+        if (formattedNickname === name) {
2506
             return;
2491
             return;
2507
         }
2492
         }
2508
 
2493
 
2509
         APP.store.dispatch(participantUpdated({
2494
         APP.store.dispatch(participantUpdated({
2510
-            id: this.getMyUserId(),
2495
+            id,
2511
             local: true,
2496
             local: true,
2512
             name: formattedNickname
2497
             name: formattedNickname
2513
         }));
2498
         }));
2515
         APP.settings.setDisplayName(formattedNickname);
2500
         APP.settings.setDisplayName(formattedNickname);
2516
         if (room) {
2501
         if (room) {
2517
             room.setDisplayName(formattedNickname);
2502
             room.setDisplayName(formattedNickname);
2518
-            APP.UI.changeDisplayName(this.getMyUserId(), formattedNickname);
2503
+            APP.UI.changeDisplayName(id, formattedNickname);
2519
         }
2504
         }
2520
     },
2505
     },
2521
 
2506
 

+ 8
- 6
modules/UI/UI.js View File

19
 import Filmstrip from "./videolayout/Filmstrip";
19
 import Filmstrip from "./videolayout/Filmstrip";
20
 import SettingsMenu from "./side_pannels/settings/SettingsMenu";
20
 import SettingsMenu from "./side_pannels/settings/SettingsMenu";
21
 import Profile from "./side_pannels/profile/Profile";
21
 import Profile from "./side_pannels/profile/Profile";
22
-import Settings from "./../settings/Settings";
23
 
22
 
24
 import { updateDeviceList } from '../../react/features/base/devices';
23
 import { updateDeviceList } from '../../react/features/base/devices';
25
 import { JitsiTrackErrors } from '../../react/features/base/lib-jitsi-meet';
24
 import { JitsiTrackErrors } from '../../react/features/base/lib-jitsi-meet';
42
     maybeShowNotificationWithDoNotDisplay,
41
     maybeShowNotificationWithDoNotDisplay,
43
     setNotificationsEnabled
42
     setNotificationsEnabled
44
 } from '../../react/features/notifications';
43
 } from '../../react/features/notifications';
44
+import { getLocalParticipant } from '../../react/features/base/participants';
45
 
45
 
46
 var EventEmitter = require("events");
46
 var EventEmitter = require("events");
47
 UI.messageHandler = messageHandler;
47
 UI.messageHandler = messageHandler;
199
  * Initialize conference UI.
199
  * Initialize conference UI.
200
  */
200
  */
201
 UI.initConference = function () {
201
 UI.initConference = function () {
202
-    let id = APP.conference.getMyUserId();
202
+    const { id, avatarID, email, name }
203
+        = getLocalParticipant(APP.store.getState());
203
 
204
 
204
     // Update default button states before showing the toolbar
205
     // Update default button states before showing the toolbar
205
     // if local role changes buttons state will be again updated.
206
     // if local role changes buttons state will be again updated.
207
 
208
 
208
     UI.showToolbar();
209
     UI.showToolbar();
209
 
210
 
210
-    let displayName = config.displayJids ? id : Settings.getDisplayName();
211
+    let displayName = config.displayJids ? id : name;
211
 
212
 
212
     if (displayName) {
213
     if (displayName) {
213
         UI.changeDisplayName('localVideoContainer', displayName);
214
         UI.changeDisplayName('localVideoContainer', displayName);
214
     }
215
     }
215
 
216
 
216
     // Make sure we configure our avatar id, before creating avatar for us
217
     // Make sure we configure our avatar id, before creating avatar for us
217
-    let email = Settings.getEmail();
218
     if (email) {
218
     if (email) {
219
         UI.setUserEmail(id, email);
219
         UI.setUserEmail(id, email);
220
     } else {
220
     } else {
221
-        UI.setUserAvatarID(id, Settings.getAvatarId());
221
+        UI.setUserAvatarID(id, avatarID);
222
     }
222
     }
223
 
223
 
224
     APP.store.dispatch(checkAutoEnableDesktopSharing());
224
     APP.store.dispatch(checkAutoEnableDesktopSharing());
235
 
235
 
236
     // Update local video now that a conference is joined a user ID should be
236
     // Update local video now that a conference is joined a user ID should be
237
     // set.
237
     // set.
238
-    UI.changeDisplayName('localVideoContainer', APP.settings.getDisplayName());
238
+    UI.changeDisplayName(
239
+        'localVideoContainer',
240
+        APP.conference.getLocalDisplayName());
239
 };
241
 };
240
 
242
 
241
 /***
243
 /***

+ 2
- 2
modules/UI/side_pannels/chat/Chat.js View File

187
      */
187
      */
188
     init (eventEmitter) {
188
     init (eventEmitter) {
189
         initHTML();
189
         initHTML();
190
-        if (APP.settings.getDisplayName()) {
190
+        if (APP.conference.getLocalDisplayName()) {
191
             Chat.setChatConversationMode(true);
191
             Chat.setChatConversationMode(true);
192
         }
192
         }
193
 
193
 
244
 
244
 
245
                 // if we are in conversation mode focus on the text input
245
                 // if we are in conversation mode focus on the text input
246
                 // if we are not, focus on the display name input
246
                 // if we are not, focus on the display name input
247
-                if (APP.settings.getDisplayName())
247
+                if (APP.conference.getLocalDisplayName())
248
                     deferredFocus('usermsg');
248
                     deferredFocus('usermsg');
249
                 else
249
                 else
250
                     deferredFocus('nickinput');
250
                     deferredFocus('nickinput');

+ 5
- 19
react/features/base/conference/actions.js View File

5
 import { setAudioMuted, setVideoMuted } from '../media';
5
 import { setAudioMuted, setVideoMuted } from '../media';
6
 import {
6
 import {
7
     dominantSpeakerChanged,
7
     dominantSpeakerChanged,
8
-    getLocalParticipant,
9
     participantConnectionStatusChanged,
8
     participantConnectionStatusChanged,
10
     participantJoined,
9
     participantJoined,
11
     participantLeft,
10
     participantLeft,
36
     EMAIL_COMMAND,
35
     EMAIL_COMMAND,
37
     JITSI_CONFERENCE_URL_KEY
36
     JITSI_CONFERENCE_URL_KEY
38
 } from './constants';
37
 } from './constants';
39
-import { _addLocalTracksToConference } from './functions';
38
+import {
39
+    _addLocalTracksToConference,
40
+    setLocalParticipantData
41
+} from './functions';
40
 
42
 
41
 import type { Dispatch } from 'redux';
43
 import type { Dispatch } from 'redux';
42
 
44
 
147
         })));
149
         })));
148
 }
150
 }
149
 
151
 
150
-/**
151
- * Sets the data for the local participant to the conference.
152
- *
153
- * @param {JitsiConference} conference - The JitsiConference instance.
154
- * @param {Object} state - The Redux state.
155
- * @returns {void}
156
- */
157
-function _setLocalParticipantData(conference, state) {
158
-    const { avatarID } = getLocalParticipant(state);
159
-
160
-    conference.removeCommand(AVATAR_ID_COMMAND);
161
-    conference.sendCommand(AVATAR_ID_COMMAND, {
162
-        value: avatarID
163
-    });
164
-}
165
-
166
 /**
152
 /**
167
  * Signals that a specific conference has failed.
153
  * Signals that a specific conference has failed.
168
  *
154
  *
302
 
288
 
303
         _addConferenceListeners(conference, dispatch);
289
         _addConferenceListeners(conference, dispatch);
304
 
290
 
305
-        _setLocalParticipantData(conference, state);
291
+        setLocalParticipantData(conference, state);
306
 
292
 
307
         conference.join(password);
293
         conference.join(password);
308
     };
294
     };

+ 29
- 0
react/features/base/conference/functions.js View File

1
+import {
2
+    AVATAR_ID_COMMAND,
3
+    AVATAR_URL_COMMAND,
4
+    EMAIL_COMMAND
5
+} from './constants';
1
 import { JitsiTrackErrors } from '../lib-jitsi-meet';
6
 import { JitsiTrackErrors } from '../lib-jitsi-meet';
7
+import { getLocalParticipant } from '../participants';
2
 import { toState } from '../redux';
8
 import { toState } from '../redux';
3
 
9
 
4
 /**
10
 /**
121
     // one.
127
     // one.
122
     console.error(msg, err);
128
     console.error(msg, err);
123
 }
129
 }
130
+
131
+/**
132
+ * Sets the data like avatar URL, email and display name for the local
133
+ * participant to the conference.
134
+ *
135
+ * @param {JitsiConference} conference - The JitsiConference instance.
136
+ * @param {Object} state - The whole Redux state.
137
+ * @returns {void}
138
+ */
139
+export function setLocalParticipantData(conference, state) {
140
+    const { avatarID, avatarURL, email, name } = getLocalParticipant(state);
141
+
142
+    avatarID && conference.sendCommand(AVATAR_ID_COMMAND, {
143
+        value: avatarID
144
+    });
145
+    avatarURL && conference.sendCommand(AVATAR_URL_COMMAND, {
146
+        value: avatarURL
147
+    });
148
+    email && conference.sendCommand(EMAIL_COMMAND, {
149
+        value: email
150
+    });
151
+    conference.setDisplayName(name);
152
+}

+ 2
- 1
react/features/base/connection/actions.web.js View File

72
 
72
 
73
             APP.keyboardshortcut.init();
73
             APP.keyboardshortcut.init();
74
 
74
 
75
-            if (config.requireDisplayName && !APP.settings.getDisplayName()) {
75
+            if (config.requireDisplayName
76
+                    && !APP.conference.getLocalDisplayName()) {
76
                 APP.UI.promptDisplayName();
77
                 APP.UI.promptDisplayName();
77
             }
78
             }
78
         })
79
         })

+ 114
- 2
react/features/base/jwt/middleware.js View File

12
 import {
12
 import {
13
     getLocalParticipant,
13
     getLocalParticipant,
14
     getParticipantCount,
14
     getParticipantCount,
15
-    PARTICIPANT_JOINED
15
+    LOCAL_PARTICIPANT_DEFAULT_NAME,
16
+    PARTICIPANT_JOINED,
17
+    participantUpdated
16
 } from '../participants';
18
 } from '../participants';
17
 import { MiddlewareRegistry } from '../redux';
19
 import { MiddlewareRegistry } from '../redux';
18
 
20
 
119
     return result;
121
     return result;
120
 }
122
 }
121
 
123
 
124
+/**
125
+ * Converts 'context.user' JWT token structure to the format compatible with the
126
+ * corresponding fields overridden in base/participants.
127
+ *
128
+ * @param {Object} user - The 'jwt.context.user' structure parsed from the JWT
129
+ * token.
130
+ * @returns {({
131
+ *      avatarURL: string?,
132
+ *      email: string?,
133
+ *      name: string?
134
+ * })}
135
+ * @private
136
+ */
137
+function _normalizeCallerFields(user) {
138
+    const { avatar, avatarUrl, email, name } = user;
139
+    const caller = { };
140
+
141
+    if (typeof (avatarUrl || avatar) === 'string') {
142
+        caller.avatarURL = (avatarUrl || avatar).trim();
143
+    }
144
+    if (typeof email === 'string') {
145
+        caller.email = email.trim();
146
+    }
147
+    if (typeof name === 'string') {
148
+        caller.name = name.trim();
149
+    }
150
+
151
+    return Object.keys(caller).length ? caller : undefined;
152
+}
153
+
154
+/**
155
+ * Eventually overwrites 'avatarURL', 'email' and 'name' fields with the values
156
+ * from JWT token for the local participant stored in the 'base/participants'
157
+ * Redux store by dispatching the participant updated action.
158
+ *
159
+ * @param {Store} store - The redux store.
160
+ * @param {Object} caller - The "caller" structure parsed from 'context.user'
161
+ * part of the JWT token and then normalized using
162
+ * {@link _normalizeCallerFields}.
163
+ * @returns {void}
164
+ * @private
165
+ */
166
+function _overwriteLocalParticipant({ dispatch, getState }, caller) {
167
+    const { avatarURL, email, name } = caller;
168
+    const localParticipant = getLocalParticipant(getState());
169
+
170
+    if (localParticipant && (avatarURL || email || name)) {
171
+        const newProperties = { id: localParticipant.id };
172
+
173
+        if (avatarURL) {
174
+            newProperties.avatarURL = avatarURL;
175
+        }
176
+        if (email) {
177
+            newProperties.email = email;
178
+        }
179
+        if (name) {
180
+            newProperties.name = name;
181
+        }
182
+        dispatch(participantUpdated(newProperties));
183
+    }
184
+}
185
+
186
+/**
187
+ * Will reset the values overridden by {@link _overwriteLocalParticipant}
188
+ * by either clearing them or setting to default values. Only the values that
189
+ * have not changed since the override happened will be restored.
190
+ *
191
+ * NOTE Once there is the possibility to edit and save participant properties,
192
+ * this method should restore values from the storage instead.
193
+ *
194
+ * @param {Store} store - The Redux store.
195
+ * @param {Object} caller - The 'caller' part of the JWT Redux state which tells
196
+ * which local participant's fields's been overridden when the JWT token was
197
+ * set.
198
+ * @returns {void}
199
+ * @private
200
+ */
201
+function _resetLocalParticipantOverrides({ dispatch, getState }, caller) {
202
+    const { avatarURL, name, email } = caller;
203
+    const localParticipant = getLocalParticipant(getState());
204
+
205
+    if (localParticipant && (avatarURL || name || email)) {
206
+        const newProperties = { id: localParticipant.id };
207
+
208
+        if (avatarURL === localParticipant.avatarURL) {
209
+            newProperties.avatarURL = undefined;
210
+        }
211
+        if (name === localParticipant.name) {
212
+            newProperties.name = LOCAL_PARTICIPANT_DEFAULT_NAME;
213
+        }
214
+        if (email === localParticipant.email) {
215
+            newProperties.email = undefined;
216
+        }
217
+        dispatch(participantUpdated(newProperties));
218
+    }
219
+}
220
+
122
 /**
221
 /**
123
  * Notifies the feature jwt that the action {@link SET_CONFIG} or
222
  * Notifies the feature jwt that the action {@link SET_CONFIG} or
124
  * {@link SET_LOCATION_URL} is being dispatched within a specific redux
223
  * {@link SET_LOCATION_URL} is being dispatched within a specific redux
183
             action.issuer = iss;
282
             action.issuer = iss;
184
             if (context) {
283
             if (context) {
185
                 action.callee = context.callee;
284
                 action.callee = context.callee;
186
-                action.caller = context.user;
285
+                action.caller = _normalizeCallerFields(context.user);
187
                 action.group = context.group;
286
                 action.group = context.group;
188
                 action.server = context.server;
287
                 action.server = context.server;
288
+
289
+                if (action.caller) {
290
+                    _overwriteLocalParticipant(store, action.caller);
291
+                }
189
             }
292
             }
190
         }
293
         }
294
+    } else if (!jwt && !Object.keys(actionPayload).length) {
295
+        const jwtState = store.getState()['features/base/jwt'];
296
+
297
+        // The logic of restoring JWT overrides make sense only on mobile. On
298
+        // web it should eventually be restored from storage, but there's no
299
+        // such use case yet.
300
+        if (jwtState.caller && typeof APP === 'undefined') {
301
+            _resetLocalParticipantOverrides(store, jwtState.caller);
302
+        }
191
     }
303
     }
192
 
304
 
193
     return _maybeSetCallOverlayVisible(store, next, action);
305
     return _maybeSetCallOverlayVisible(store, next, action);

+ 7
- 0
react/features/base/participants/constants.js View File

21
  */
21
  */
22
 export const LOCAL_PARTICIPANT_DEFAULT_ID = 'local';
22
 export const LOCAL_PARTICIPANT_DEFAULT_ID = 'local';
23
 
23
 
24
+/**
25
+ * The default display name for the local participant.
26
+ * TODO Get the from config and/or localized.
27
+ * @type {string}
28
+ */
29
+export const LOCAL_PARTICIPANT_DEFAULT_NAME = 'me';
30
+
24
 /**
31
 /**
25
  * Max length of the display names.
32
  * Max length of the display names.
26
  *
33
  *

+ 7
- 1
react/features/base/participants/reducer.js View File

11
 } from './actionTypes';
11
 } from './actionTypes';
12
 import {
12
 import {
13
     LOCAL_PARTICIPANT_DEFAULT_ID,
13
     LOCAL_PARTICIPANT_DEFAULT_ID,
14
+    LOCAL_PARTICIPANT_DEFAULT_NAME,
14
     PARTICIPANT_ROLE
15
     PARTICIPANT_ROLE
15
 } from './constants';
16
 } from './constants';
16
 
17
 
99
         // name
100
         // name
100
         if (!name) {
101
         if (!name) {
101
             // TODO Get the from config and/or localized.
102
             // TODO Get the from config and/or localized.
102
-            name = local ? 'me' : 'Fellow Jitster';
103
+            // On web default value is handled in:
104
+            // conference.js getParticipantDisplayName
105
+            if (typeof APP === 'undefined') {
106
+                name
107
+                    = local ? LOCAL_PARTICIPANT_DEFAULT_NAME : 'Fellow Jitster';
108
+            }
103
         }
109
         }
104
 
110
 
105
         return {
111
         return {

+ 0
- 21
react/features/conference/route.js View File

29
  * @returns {void}
29
  * @returns {void}
30
  */
30
  */
31
 function _initConference() {
31
 function _initConference() {
32
-    _setTokenData();
33
-
34
     // Initialize the conference URL handler
32
     // Initialize the conference URL handler
35
     APP.ConferenceUrl = new ConferenceUrl(window.location);
33
     APP.ConferenceUrl = new ConferenceUrl(window.location);
36
 }
34
 }
102
     APP.connectionTimes['configuration.fetched'] = now;
100
     APP.connectionTimes['configuration.fetched'] = now;
103
     logger.log('(TIME) configuration fetched:\t', now);
101
     logger.log('(TIME) configuration fetched:\t', now);
104
 }
102
 }
105
-
106
-/**
107
- * If JWT token data it will be used for local user settings.
108
- *
109
- * @private
110
- * @returns {void}
111
- */
112
-function _setTokenData() {
113
-    const state = APP.store.getState();
114
-    const { caller } = state['features/base/jwt'];
115
-
116
-    if (caller) {
117
-        const { avatarUrl, avatar, email, name } = caller;
118
-
119
-        APP.settings.setEmail((email || '').trim(), true);
120
-        APP.settings.setAvatarUrl((avatarUrl || avatar || '').trim());
121
-        APP.settings.setDisplayName((name || '').trim(), true);
122
-    }
123
-}

+ 3
- 3
react/features/filmstrip/functions.js View File

3
 declare var interfaceConfig: Object;
3
 declare var interfaceConfig: Object;
4
 
4
 
5
 import {
5
 import {
6
-    getPinnedParticipant,
7
-    getLocalParticipant
6
+    getPinnedParticipant
8
 } from '../base/participants';
7
 } from '../base/participants';
9
 
8
 
10
 /**
9
 /**
17
 export function shouldRemoteVideosBeVisible(state: Object) {
16
 export function shouldRemoteVideosBeVisible(state: Object) {
18
     const participants = state['features/base/participants'];
17
     const participants = state['features/base/participants'];
19
     const participantsCount = participants.length;
18
     const participantsCount = participants.length;
19
+    const pinnedParticipant = getPinnedParticipant(state);
20
 
20
 
21
     const shouldShowVideos
21
     const shouldShowVideos
22
         = participantsCount > 2
22
         = participantsCount > 2
27
         || (participantsCount > 1
27
         || (participantsCount > 1
28
             && (state['features/filmstrip'].hovered
28
             && (state['features/filmstrip'].hovered
29
                 || state['features/toolbox'].visible
29
                 || state['features/toolbox'].visible
30
-                || getLocalParticipant(state) === getPinnedParticipant(state)))
30
+                || (pinnedParticipant && pinnedParticipant.local)))
31
 
31
 
32
         || interfaceConfig.filmStripOnly
32
         || interfaceConfig.filmStripOnly
33
 
33
 

+ 33
- 4
react/features/speaker-stats/components/SpeakerStats.js View File

1
-/* global APP, interfaceConfig */
1
+/* global interfaceConfig */
2
 
2
 
3
 import PropTypes from 'prop-types';
3
 import PropTypes from 'prop-types';
4
 import React, { Component } from 'react';
4
 import React, { Component } from 'react';
5
+import { connect } from 'react-redux';
5
 
6
 
6
 import { Dialog } from '../../base/dialog';
7
 import { Dialog } from '../../base/dialog';
7
 import { translate } from '../../base/i18n';
8
 import { translate } from '../../base/i18n';
8
-
9
+import { getLocalParticipant } from '../../base/participants';
9
 import SpeakerStatsItem from './SpeakerStatsItem';
10
 import SpeakerStatsItem from './SpeakerStatsItem';
10
 import SpeakerStatsLabels from './SpeakerStatsLabels';
11
 import SpeakerStatsLabels from './SpeakerStatsLabels';
11
 
12
 
21
      * @static
22
      * @static
22
      */
23
      */
23
     static propTypes = {
24
     static propTypes = {
25
+        /**
26
+         * The display name for the local participant obtained from the Redux
27
+         * store.
28
+         */
29
+        _localDisplayName: PropTypes.string,
30
+
24
         /**
31
         /**
25
          * The JitsiConference from which stats will be pulled.
32
          * The JitsiConference from which stats will be pulled.
26
          */
33
          */
130
             const { t } = this.props;
137
             const { t } = this.props;
131
             const meString = t('me');
138
             const meString = t('me');
132
 
139
 
133
-            displayName = APP.settings.getDisplayName();
140
+            displayName = this.props._localDisplayName;
134
             displayName = displayName ? `${displayName} (${meString})`
141
             displayName = displayName ? `${displayName} (${meString})`
135
                 : meString;
142
                 : meString;
136
         } else {
143
         } else {
149
     }
156
     }
150
 }
157
 }
151
 
158
 
152
-export default translate(SpeakerStats);
159
+/**
160
+ * Maps (parts of) the Redux state to the associated SpeakerStats's props.
161
+ *
162
+ * @param {Object} state - The Redux state.
163
+ * @private
164
+ * @returns {{
165
+ *     _localDisplayName: string?
166
+ * }}
167
+ */
168
+function _mapStateToProps(state) {
169
+    const localParticipant = getLocalParticipant(state);
170
+
171
+    return {
172
+        /**
173
+         * The local display name.
174
+         * @private
175
+         * @type {string|undefined}
176
+         */
177
+        _localDisplayName: localParticipant && localParticipant.name
178
+    };
179
+}
180
+
181
+export default translate(connect(_mapStateToProps)(SpeakerStats));

Loading…
Cancel
Save