Преглед на файлове

Associate remote participant w/ JitsiConference (_UPDATED)

The commit message of "Associate remote participant w/ JitsiConference
(_JOINED)" explains the motivation for this commit.

Practically, _JOINED and _LEFT combined with "Remove remote participants
who are no longer of interest" should alleviate the problem with
multiplying remote participants to an acceptable level of annoyance.

Technically though, a remote participant cannot be identified by an ID
only. The ID is (somewhat) "unique" in the context of a single
JitsiConference instance. So in order to not have to scratch our heads
over an obscure corner, racing case, it's better to always identify
remote participants by the pair id-conference. Unfortunately, that's a
bit of a high order given the existing source code. So I've implemented
the cases which are the easiest so that new source code written with
participantUpdated is more likely to identify a remote participant with
the pair id-conference.

Additionally, the commit "Reduce direct read access to the
features/base/participants redux state" brings more control back to the
functions of the feature base/participants so that one day we can (if we
choose to) do something like, for example:

If getParticipants is called with a conference, it returns the
participants from features/base/participants who are associated with the
specified conference. If no conference is specified in the function
call, then default to the conference which is the primary focus of the
app at the time of the function call. Added to the above, this should
allow us to further reduce the cases in which we're identifying remote
participants by id only and get us even closer to a more "predictable"
behavior in corner, racing cases.
master
Lyubo Marinov преди 7 години
родител
ревизия
771d60f954

+ 26
- 3
conference.js Целия файл

1804
 
1804
 
1805
                 APP.UI.participantConnectionStatusChanged(id);
1805
                 APP.UI.participantConnectionStatusChanged(id);
1806
             });
1806
             });
1807
-        room.on(JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED, id => {
1808
-            APP.store.dispatch(dominantSpeakerChanged(id));
1809
-        });
1807
+        room.on(
1808
+            JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED,
1809
+            id => APP.store.dispatch(dominantSpeakerChanged(id, room)));
1810
 
1810
 
1811
         if (!interfaceConfig.filmStripOnly) {
1811
         if (!interfaceConfig.filmStripOnly) {
1812
             room.on(JitsiConferenceEvents.CONNECTION_INTERRUPTED, () => {
1812
             room.on(JitsiConferenceEvents.CONNECTION_INTERRUPTED, () => {
1883
                     = displayName.substr(0, MAX_DISPLAY_NAME_LENGTH);
1883
                     = displayName.substr(0, MAX_DISPLAY_NAME_LENGTH);
1884
 
1884
 
1885
                 APP.store.dispatch(participantUpdated({
1885
                 APP.store.dispatch(participantUpdated({
1886
+                    conference: room,
1886
                     id,
1887
                     id,
1887
                     name: formattedDisplayName
1888
                     name: formattedDisplayName
1888
                 }));
1889
                 }));
1916
                 switch (name) {
1917
                 switch (name) {
1917
                 case 'raisedHand':
1918
                 case 'raisedHand':
1918
                     APP.store.dispatch(participantUpdated({
1919
                     APP.store.dispatch(participantUpdated({
1920
+                        conference: room,
1919
                         id: participant.getId(),
1921
                         id: participant.getId(),
1920
                         raisedHand: newValue === 'true'
1922
                         raisedHand: newValue === 'true'
1921
                     }));
1923
                     }));
2015
         APP.UI.addListener(UIEvents.EMAIL_CHANGED, this.changeLocalEmail);
2017
         APP.UI.addListener(UIEvents.EMAIL_CHANGED, this.changeLocalEmail);
2016
         room.addCommandListener(this.commands.defaults.EMAIL, (data, from) => {
2018
         room.addCommandListener(this.commands.defaults.EMAIL, (data, from) => {
2017
             APP.store.dispatch(participantUpdated({
2019
             APP.store.dispatch(participantUpdated({
2020
+                conference: room,
2018
                 id: from,
2021
                 id: from,
2019
                 email: data.value
2022
                 email: data.value
2020
             }));
2023
             }));
2026
             (data, from) => {
2029
             (data, from) => {
2027
                 APP.store.dispatch(
2030
                 APP.store.dispatch(
2028
                     participantUpdated({
2031
                     participantUpdated({
2032
+                        conference: room,
2029
                         id: from,
2033
                         id: from,
2030
                         avatarURL: data.value
2034
                         avatarURL: data.value
2031
                     }));
2035
                     }));
2035
             (data, from) => {
2039
             (data, from) => {
2036
                 APP.store.dispatch(
2040
                 APP.store.dispatch(
2037
                     participantUpdated({
2041
                     participantUpdated({
2042
+                        conference: room,
2038
                         id: from,
2043
                         id: from,
2039
                         avatarID: data.value
2044
                         avatarID: data.value
2040
                     }));
2045
                     }));
2579
         const localId = localParticipant.id;
2584
         const localId = localParticipant.id;
2580
 
2585
 
2581
         APP.store.dispatch(participantUpdated({
2586
         APP.store.dispatch(participantUpdated({
2587
+            // XXX Only the local participant is allowed to update without
2588
+            // stating the JitsiConference instance (i.e. participant property
2589
+            // `conference` for a remote participant) because the local
2590
+            // participant is uniquely identified by the very fact that there is
2591
+            // only one local participant.
2592
+
2582
             id: localId,
2593
             id: localId,
2583
             local: true,
2594
             local: true,
2584
             email: formattedEmail
2595
             email: formattedEmail
2606
         }
2617
         }
2607
 
2618
 
2608
         APP.store.dispatch(participantUpdated({
2619
         APP.store.dispatch(participantUpdated({
2620
+            // XXX Only the local participant is allowed to update without
2621
+            // stating the JitsiConference instance (i.e. participant property
2622
+            // `conference` for a remote participant) because the local
2623
+            // participant is uniquely identified by the very fact that there is
2624
+            // only one local participant.
2625
+
2609
             id,
2626
             id,
2610
             local: true,
2627
             local: true,
2611
             avatarURL: formattedUrl
2628
             avatarURL: formattedUrl
2662
         }
2679
         }
2663
 
2680
 
2664
         APP.store.dispatch(participantUpdated({
2681
         APP.store.dispatch(participantUpdated({
2682
+            // XXX Only the local participant is allowed to update without
2683
+            // stating the JitsiConference instance (i.e. participant property
2684
+            // `conference` for a remote participant) because the local
2685
+            // participant is uniquely identified by the very fact that there is
2686
+            // only one local participant.
2687
+
2665
             id,
2688
             id,
2666
             local: true,
2689
             local: true,
2667
             name: formattedNickname
2690
             name: formattedNickname

+ 5
- 1
react/features/base/conference/actions.js Целия файл

125
     conference.on(
125
     conference.on(
126
         JitsiConferenceEvents.DISPLAY_NAME_CHANGED,
126
         JitsiConferenceEvents.DISPLAY_NAME_CHANGED,
127
         (id, displayName) => dispatch(participantUpdated({
127
         (id, displayName) => dispatch(participantUpdated({
128
+            conference,
128
             id,
129
             id,
129
             name: displayName.substr(0, MAX_DISPLAY_NAME_LENGTH)
130
             name: displayName.substr(0, MAX_DISPLAY_NAME_LENGTH)
130
         })));
131
         })));
131
 
132
 
132
     conference.on(
133
     conference.on(
133
         JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED,
134
         JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED,
134
-        (...args) => dispatch(dominantSpeakerChanged(...args)));
135
+        id => dispatch(dominantSpeakerChanged(id, conference)));
135
 
136
 
136
     conference.on(
137
     conference.on(
137
         JitsiConferenceEvents.PARTICIPANT_CONN_STATUS_CHANGED,
138
         JitsiConferenceEvents.PARTICIPANT_CONN_STATUS_CHANGED,
155
     conference.addCommandListener(
156
     conference.addCommandListener(
156
         AVATAR_ID_COMMAND,
157
         AVATAR_ID_COMMAND,
157
         (data, id) => dispatch(participantUpdated({
158
         (data, id) => dispatch(participantUpdated({
159
+            conference,
158
             id,
160
             id,
159
             avatarID: data.value
161
             avatarID: data.value
160
         })));
162
         })));
161
     conference.addCommandListener(
163
     conference.addCommandListener(
162
         AVATAR_URL_COMMAND,
164
         AVATAR_URL_COMMAND,
163
         (data, id) => dispatch(participantUpdated({
165
         (data, id) => dispatch(participantUpdated({
166
+            conference,
164
             id,
167
             id,
165
             avatarURL: data.value
168
             avatarURL: data.value
166
         })));
169
         })));
167
     conference.addCommandListener(
170
     conference.addCommandListener(
168
         EMAIL_COMMAND,
171
         EMAIL_COMMAND,
169
         (data, id) => dispatch(participantUpdated({
172
         (data, id) => dispatch(participantUpdated({
173
+            conference,
170
             id,
174
             id,
171
             email: data.value
175
             email: data.value
172
         })));
176
         })));

+ 8
- 2
react/features/base/jwt/middleware.js Целия файл

143
 
143
 
144
     if ((avatarURL || email || name)
144
     if ((avatarURL || email || name)
145
             && (localParticipant = getLocalParticipant(getState))) {
145
             && (localParticipant = getLocalParticipant(getState))) {
146
-        const newProperties: Object = { id: localParticipant.id };
146
+        const newProperties: Object = {
147
+            id: localParticipant.id,
148
+            local: true
149
+        };
147
 
150
 
148
         if (avatarURL) {
151
         if (avatarURL) {
149
             newProperties.avatarURL = avatarURL;
152
             newProperties.avatarURL = avatarURL;
264
 
267
 
265
     if ((avatarURL || name || email)
268
     if ((avatarURL || name || email)
266
             && (localParticipant = getLocalParticipant(getState))) {
269
             && (localParticipant = getLocalParticipant(getState))) {
267
-        const newProperties: Object = { id: localParticipant.id };
270
+        const newProperties: Object = {
271
+            id: localParticipant.id,
272
+            local: true
273
+        };
268
 
274
 
269
         if (avatarURL === localParticipant.avatarURL) {
275
         if (avatarURL === localParticipant.avatarURL) {
270
             newProperties.avatarURL = undefined;
276
             newProperties.avatarURL = undefined;

+ 7
- 1
react/features/base/participants/actions.js Целия файл

22
  * Create an action for when dominant speaker changes.
22
  * Create an action for when dominant speaker changes.
23
  *
23
  *
24
  * @param {string} id - Participant's ID.
24
  * @param {string} id - Participant's ID.
25
+ * @param {JitsiConference} conference - The {@code JitsiConference} associated
26
+ * with the participant identified by the specified {@code id}. Only the local
27
+ * participant is allowed to not specify an associated {@code JitsiConference}
28
+ * instance.
25
  * @returns {{
29
  * @returns {{
26
  *     type: DOMINANT_SPEAKER_CHANGED,
30
  *     type: DOMINANT_SPEAKER_CHANGED,
27
  *     participant: {
31
  *     participant: {
32
+ *         conference: JitsiConference,
28
  *         id: string
33
  *         id: string
29
  *     }
34
  *     }
30
  * }}
35
  * }}
31
  */
36
  */
32
-export function dominantSpeakerChanged(id) {
37
+export function dominantSpeakerChanged(id, conference) {
33
     return {
38
     return {
34
         type: DOMINANT_SPEAKER_CHANGED,
39
         type: DOMINANT_SPEAKER_CHANGED,
35
         participant: {
40
         participant: {
41
+            conference,
36
             id
42
             id
37
         }
43
         }
38
     };
44
     };

+ 1
- 3
react/features/base/participants/functions.js Целия файл

127
  * @private
127
  * @private
128
  * @returns {(Participant|undefined)}
128
  * @returns {(Participant|undefined)}
129
  */
129
  */
130
-export function getParticipantById(
131
-        stateful: Object | Function,
132
-        id: string) {
130
+export function getParticipantById(stateful: Object | Function, id: string) {
133
     const participants = _getAllParticipants(stateful);
131
     const participants = _getAllParticipants(stateful);
134
 
132
 
135
     return participants.find(p => p.id === id);
133
     return participants.find(p => p.id === id);

+ 6
- 7
react/features/base/participants/middleware.js Целия файл

63
 
63
 
64
     case DOMINANT_SPEAKER_CHANGED: {
64
     case DOMINANT_SPEAKER_CHANGED: {
65
         // Ensure the raised hand state is cleared for the dominant speaker.
65
         // Ensure the raised hand state is cleared for the dominant speaker.
66
-        const participant = getLocalParticipant(store.getState());
67
 
66
 
68
-        if (participant) {
69
-            const { id } = action.participant;
67
+        const { conference, id } = action.participant;
68
+        const participant = getLocalParticipant(store.getState());
70
 
69
 
71
-            store.dispatch(participantUpdated({
70
+        participant
71
+            && store.dispatch(participantUpdated({
72
+                conference,
72
                 id,
73
                 id,
73
                 local: participant.id === id,
74
                 local: participant.id === id,
74
                 raisedHand: false
75
                 raisedHand: false
75
             }));
76
             }));
76
-        }
77
 
77
 
78
-        typeof APP === 'object'
79
-            && APP.UI.markDominantSpeaker(action.participant.id);
78
+        typeof APP === 'object' && APP.UI.markDominantSpeaker(id);
80
 
79
 
81
         break;
80
         break;
82
     }
81
     }

+ 16
- 4
react/features/base/participants/reducer.js Целия файл

32
 declare var APP: Object;
32
 declare var APP: Object;
33
 
33
 
34
 /**
34
 /**
35
- * These properties should not be bulk assigned when updating a particular
36
- * @see Participant.
35
+ * The participant properties which cannot be updated through
36
+ * {@link PARTICIPANT_UPDATED}. They either identify the participant or can only
37
+ * be modified through property-dedicated actions.
38
+ *
37
  * @type {string[]}
39
  * @type {string[]}
38
  */
40
  */
39
-const PARTICIPANT_PROPS_TO_OMIT_WHEN_UPDATE
40
-    = [ 'dominantSpeaker', 'id', 'local', 'pinned' ];
41
+const PARTICIPANT_PROPS_TO_OMIT_WHEN_UPDATE = [
42
+
43
+    // The following properties identify the participant:
44
+    'conference',
45
+    'id',
46
+    'local',
47
+
48
+    // The following properties can only be modified through property-dedicated
49
+    // actions:
50
+    'dominantSpeaker',
51
+    'pinned'
52
+];
41
 
53
 
42
 /**
54
 /**
43
  * Listen for actions which add, remove, or update the set of participants in
55
  * Listen for actions which add, remove, or update the set of participants in

+ 6
- 0
react/features/toolbox/components/web/Toolbox.js Целия файл

505
         const { _localParticipantID, _raisedHand } = this.props;
505
         const { _localParticipantID, _raisedHand } = this.props;
506
 
506
 
507
         this.props.dispatch(participantUpdated({
507
         this.props.dispatch(participantUpdated({
508
+            // XXX Only the local participant is allowed to update without
509
+            // stating the JitsiConference instance (i.e. participant property
510
+            // `conference` for a remote participant) because the local
511
+            // participant is uniquely identified by the very fact that there is
512
+            // only one local participant.
513
+
508
             id: _localParticipantID,
514
             id: _localParticipantID,
509
             local: true,
515
             local: true,
510
             raisedHand: !_raisedHand
516
             raisedHand: !_raisedHand

Loading…
Отказ
Запис