소스 검색

Merge pull request #1440 from jitsi/iframe_api_race_condition

Fix executeCommand race condition
master
Saúl Ibarra Corretgé 8 년 전
부모
커밋
a10f040df6

+ 55
- 29
conference.js 파일 보기

@@ -32,12 +32,10 @@ import {
32 32
     isFatalJitsiConnectionError
33 33
 } from './react/features/base/lib-jitsi-meet';
34 34
 import {
35
-    changeParticipantAvatarID,
36
-    changeParticipantAvatarURL,
37
-    changeParticipantEmail,
38 35
     participantJoined,
39 36
     participantLeft,
40
-    participantRoleChanged
37
+    participantRoleChanged,
38
+    participantUpdated
41 39
 } from './react/features/base/participants';
42 40
 import {
43 41
     showDesktopPicker
@@ -174,6 +172,10 @@ function createInitialLocalTracksAndConnect(roomName) {
174 172
  * @param {string} value new value
175 173
  */
176 174
 function sendData (command, value) {
175
+    if(!room) {
176
+        return;
177
+    }
178
+
177 179
     room.removeCommand(command);
178 180
     room.sendCommand(command, {value: value});
179 181
 }
@@ -361,23 +363,6 @@ function createLocalTracks (options, checkForPermissionPrompt) {
361 363
         });
362 364
 }
363 365
 
364
-/**
365
- * Changes the display name for the local user
366
- * @param nickname {string} the new display name
367
- */
368
-function changeLocalDisplayName(nickname = '') {
369
-    const formattedNickname
370
-        = nickname.trim().substr(0, MAX_DISPLAY_NAME_LENGTH);
371
-
372
-    if (formattedNickname === APP.settings.getDisplayName()) {
373
-        return;
374
-    }
375
-
376
-    APP.settings.setDisplayName(formattedNickname);
377
-    room.setDisplayName(formattedNickname);
378
-    APP.UI.changeDisplayName(APP.conference.getMyUserId(), formattedNickname);
379
-}
380
-
381 366
 class ConferenceConnector {
382 367
     constructor(resolve, reject, invite) {
383 368
         this._resolve = resolve;
@@ -1499,7 +1484,10 @@ export default {
1499 1484
 
1500 1485
         APP.UI.addListener(UIEvents.EMAIL_CHANGED, this.changeLocalEmail);
1501 1486
         room.addCommandListener(this.commands.defaults.EMAIL, (data, from) => {
1502
-            APP.store.dispatch(changeParticipantEmail(from, data.value));
1487
+            APP.store.dispatch(participantUpdated({
1488
+                id: from,
1489
+                email: data.value
1490
+            }));
1503 1491
             APP.UI.setUserEmail(from, data.value);
1504 1492
         });
1505 1493
 
@@ -1507,18 +1495,25 @@ export default {
1507 1495
             this.commands.defaults.AVATAR_URL,
1508 1496
             (data, from) => {
1509 1497
                 APP.store.dispatch(
1510
-                    changeParticipantAvatarURL(from, data.value));
1498
+                    participantUpdated({
1499
+                        id: from,
1500
+                        avatarURL: data.value
1501
+                    }));
1511 1502
                 APP.UI.setUserAvatarUrl(from, data.value);
1512 1503
         });
1513 1504
 
1514 1505
         room.addCommandListener(this.commands.defaults.AVATAR_ID,
1515 1506
             (data, from) => {
1516 1507
                 APP.store.dispatch(
1517
-                    changeParticipantAvatarID(from, data.value));
1508
+                    participantUpdated({
1509
+                        id: from,
1510
+                        avatarID: data.value
1511
+                    }));
1518 1512
                 APP.UI.setUserAvatarID(from, data.value);
1519 1513
             });
1520 1514
 
1521
-        APP.UI.addListener(UIEvents.NICKNAME_CHANGED, changeLocalDisplayName);
1515
+        APP.UI.addListener(UIEvents.NICKNAME_CHANGED,
1516
+            this.changeLocalDisplayName.bind(this));
1522 1517
 
1523 1518
         APP.UI.addListener(UIEvents.START_MUTED_CHANGED,
1524 1519
             (startAudioMuted, startVideoMuted) => {
@@ -1925,10 +1920,17 @@ export default {
1925 1920
         if (email === APP.settings.getEmail()) {
1926 1921
             return;
1927 1922
         }
1928
-        APP.store.dispatch(changeParticipantEmail(room.myUserId(), email));
1923
+
1924
+        const localId = room ? room.myUserId() : undefined;
1925
+
1926
+        APP.store.dispatch(participantUpdated({
1927
+            id: localId,
1928
+            local: true,
1929
+            email
1930
+        }));
1929 1931
 
1930 1932
         APP.settings.setEmail(email);
1931
-        APP.UI.setUserEmail(room.myUserId(), email);
1933
+        APP.UI.setUserEmail(localId, email);
1932 1934
         sendData(commands.EMAIL, email);
1933 1935
     },
1934 1936
 
@@ -1942,10 +1944,17 @@ export default {
1942 1944
         if (url === APP.settings.getAvatarUrl()) {
1943 1945
             return;
1944 1946
         }
1945
-        APP.store.dispatch(changeParticipantAvatarURL(room.myUserId(), url));
1947
+
1948
+        const localId = room ? room.myUserId() : undefined;
1949
+
1950
+        APP.store.dispatch(participantUpdated({
1951
+            id: localId,
1952
+            local: true,
1953
+            avatarURL: url
1954
+        }));
1946 1955
 
1947 1956
         APP.settings.setAvatarUrl(url);
1948
-        APP.UI.setUserAvatarUrl(room.myUserId(), url);
1957
+        APP.UI.setUserAvatarUrl(localId, url);
1949 1958
         sendData(commands.AVATAR_URL, url);
1950 1959
     },
1951 1960
 
@@ -1991,5 +2000,22 @@ export default {
1991 2000
      */
1992 2001
     isInLastN (participantId) {
1993 2002
         return room.isInLastN(participantId);
2003
+    },
2004
+    /**
2005
+     * Changes the display name for the local user
2006
+     * @param nickname {string} the new display name
2007
+     */
2008
+    changeLocalDisplayName(nickname = '') {
2009
+        const formattedNickname
2010
+            = nickname.trim().substr(0, MAX_DISPLAY_NAME_LENGTH);
2011
+
2012
+        if (formattedNickname === APP.settings.getDisplayName()) {
2013
+            return;
2014
+        }
2015
+
2016
+        APP.settings.setDisplayName(formattedNickname);
2017
+        room.setDisplayName(formattedNickname);
2018
+        APP.UI.changeDisplayName(this.getMyUserId(),
2019
+            formattedNickname);
1994 2020
     }
1995 2021
 };

+ 2
- 1
modules/API/API.js 파일 보기

@@ -45,7 +45,8 @@ let enabled = false;
45 45
 
46 46
 function initCommands() {
47 47
     commands = {
48
-        "display-name": APP.UI.inputDisplayNameHandler,
48
+        "display-name":
49
+            APP.conference.changeLocalDisplayName.bind(APP.conference),
49 50
         "toggle-audio": APP.conference.toggleAudioMuted.bind(APP.conference),
50 51
         "toggle-video": APP.conference.toggleVideoMuted.bind(APP.conference),
51 52
         "toggle-film-strip": APP.UI.toggleFilmStrip,

+ 3
- 0
modules/UI/UI.js 파일 보기

@@ -762,6 +762,9 @@ UI.setUserEmail = function (id, email) {
762 762
     Avatar.setUserEmail(id, email);
763 763
 
764 764
     changeAvatar(id, Avatar.getAvatarUrl(id));
765
+    if (APP.conference.isLocalId(id)) {
766
+        Profile.changeEmail(email);
767
+    }
765 768
 };
766 769
 
767 770
 /**

+ 2
- 2
modules/UI/avatar/Avatar.js 파일 보기

@@ -30,7 +30,7 @@ let users = {};
30 30
 export default {
31 31
     /**
32 32
      * Sets prop in users object.
33
-     * @param id {string} user id
33
+     * @param id {string} user id or undefined for the local user.
34 34
      * @param prop {string} name of the prop
35 35
      * @param val {string} value to be set
36 36
      */
@@ -38,7 +38,7 @@ export default {
38 38
         // FIXME: Fixes the issue with not be able to return avatar for the
39 39
         // local user when the conference has been left. Maybe there is beter
40 40
         // way to solve it.
41
-        if(APP.conference.isLocalId(id)) {
41
+        if(!id || APP.conference.isLocalId(id)) {
42 42
             id = "local";
43 43
         }
44 44
         if(!val || (users[id] && users[id][prop] === val))

+ 10
- 2
modules/UI/side_pannels/profile/Profile.js 파일 보기

@@ -15,10 +15,10 @@ const htmlStr = `
15 15
         </div>
16 16
         <div class="sideToolbarBlock">
17 17
             <label data-i18n="profile.setEmailLabel"></label>
18
-            <input id="setEmail" type="text" class="input-control" 
18
+            <input id="setEmail" type="text" class="input-control"
19 19
                 data-i18n="[placeholder]profile.setEmailInput">
20 20
         </div>
21
-        <div id="profile_auth_container" 
21
+        <div id="profile_auth_container"
22 22
              class="sideToolbarBlock auth_container">
23 23
             <p data-i18n="toolbar.authenticate"></p>
24 24
             <ul>
@@ -122,6 +122,14 @@ export default {
122 122
         $('#avatar').attr('src', avatarUrl);
123 123
     },
124 124
 
125
+    /**
126
+     * Change the value of the field for the user email.
127
+     * @param {string} email the new value that will be displayed in the field.
128
+     */
129
+    changeEmail (email) {
130
+        $('#setEmail').val(email);
131
+    },
132
+
125 133
     /**
126 134
      * Shows or hides authentication related buttons
127 135
      * @param {boolean} show <tt>true</tt> to show or <tt>false</tt> to hide

+ 14
- 7
react/features/base/conference/actions.js 파일 보기

@@ -1,13 +1,11 @@
1 1
 import { JitsiConferenceEvents } from '../lib-jitsi-meet';
2 2
 import {
3
-    changeParticipantAvatarID,
4
-    changeParticipantAvatarURL,
5
-    changeParticipantEmail,
6 3
     dominantSpeakerChanged,
7 4
     getLocalParticipant,
8 5
     participantJoined,
9 6
     participantLeft,
10
-    participantRoleChanged
7
+    participantRoleChanged,
8
+    participantUpdated
11 9
 } from '../participants';
12 10
 import { trackAdded, trackRemoved } from '../tracks';
13 11
 
@@ -81,13 +79,22 @@ function _addConferenceListeners(conference, dispatch) {
81 79
 
82 80
     conference.addCommandListener(
83 81
             AVATAR_ID_COMMAND,
84
-            (data, id) => dispatch(changeParticipantAvatarID(id, data.value)));
82
+            (data, id) => dispatch(participantUpdated({
83
+                id,
84
+                avatarID: data.value
85
+            })));
85 86
     conference.addCommandListener(
86 87
             AVATAR_URL_COMMAND,
87
-            (data, id) => dispatch(changeParticipantAvatarURL(id, data.value)));
88
+            (data, id) => dispatch(participantUpdated({
89
+                id,
90
+                avatarURL: data.value
91
+            })));
88 92
     conference.addCommandListener(
89 93
             EMAIL_COMMAND,
90
-            (data, id) => dispatch(changeParticipantEmail(id, data.value)));
94
+            (data, id) => dispatch(participantUpdated({
95
+                id,
96
+                email: data.value
97
+            })));
91 98
 }
92 99
 
93 100
 /**

+ 20
- 73
react/features/base/participants/actions.js 파일 보기

@@ -8,75 +8,6 @@ import {
8 8
 } from './actionTypes';
9 9
 import { getLocalParticipant } from './functions';
10 10
 
11
-/**
12
- * Action to update a participant's avatar ID.
13
- *
14
- * @param {string} id - Participant's ID.
15
- * @param {string} avatarID - Participant's avatar ID.
16
- * @returns {{
17
- *     type: PARTICIPANT_UPDATED,
18
- *     participant: {
19
- *         id: string,
20
- *         avatarID: string,
21
- *     }
22
- * }}
23
- */
24
-export function changeParticipantAvatarID(id, avatarID) {
25
-    return {
26
-        type: PARTICIPANT_UPDATED,
27
-        participant: {
28
-            id,
29
-            avatarID
30
-        }
31
-    };
32
-}
33
-
34
-/**
35
- * Action to update a participant's avatar URL.
36
- *
37
- * @param {string} id - Participant's ID.
38
- * @param {string} avatarURL - Participant's avatar URL.
39
- * @returns {{
40
- *     type: PARTICIPANT_UPDATED,
41
- *     participant: {
42
- *         id: string,
43
- *         avatarURL: string,
44
- *     }
45
- * }}
46
- */
47
-export function changeParticipantAvatarURL(id, avatarURL) {
48
-    return {
49
-        type: PARTICIPANT_UPDATED,
50
-        participant: {
51
-            id,
52
-            avatarURL
53
-        }
54
-    };
55
-}
56
-
57
-/**
58
- * Action to update a participant's email.
59
- *
60
- * @param {string} id - Participant's ID.
61
- * @param {string} email - Participant's email.
62
- * @returns {{
63
- *     type: PARTICIPANT_UPDATED,
64
- *     participant: {
65
- *         id: string,
66
- *         email: string
67
- *     }
68
- * }}
69
- */
70
-export function changeParticipantEmail(id, email) {
71
-    return {
72
-        type: PARTICIPANT_UPDATED,
73
-        participant: {
74
-            id,
75
-            email
76
-        }
77
-    };
78
-}
79
-
80 11
 /**
81 12
  * Create an action for when dominant speaker changes.
82 13
  *
@@ -203,12 +134,28 @@ export function participantLeft(id) {
203 134
  * }}
204 135
  */
205 136
 export function participantRoleChanged(id, role) {
137
+    return participantUpdated({
138
+        id,
139
+        role
140
+    });
141
+}
142
+
143
+/**
144
+ * Action to signal that some of participant properties has been changed.
145
+ *
146
+ * @param {Participant} participant={} - Information about participant. To
147
+ * identify the participant the object should contain either property id with
148
+ * value the id of the participant or property local with value true (if the
149
+ * local participant hasn't joined the conference yet).
150
+ * @returns {{
151
+ *     type: PARTICIPANT_UPDATED,
152
+ *     participant: Participant
153
+ * }}
154
+ */
155
+export function participantUpdated(participant = {}) {
206 156
     return {
207 157
         type: PARTICIPANT_UPDATED,
208
-        participant: {
209
-            id,
210
-            role
211
-        }
158
+        participant
212 159
     };
213 160
 }
214 161
 

+ 6
- 1
react/features/base/participants/reducer.js 파일 보기

@@ -112,7 +112,12 @@ function _participant(state, action) {
112 112
 
113 113
     case PARTICIPANT_UPDATED: {
114 114
         const participant = action.participant; // eslint-disable-line no-shadow
115
-        const { id } = participant;
115
+        const { local } = participant;
116
+        let { id } = participant;
117
+
118
+        if (!id && local) {
119
+            id = LOCAL_PARTICIPANT_DEFAULT_ID;
120
+        }
116 121
 
117 122
         if (state.id === id) {
118 123
             const newState = { ...state };

Loading…
취소
저장