Browse Source

Reduce the number of unnecessary Redux state changes

master
Lyubomir Marinov 8 years ago
parent
commit
4d335e086b

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

46
             return {
46
             return {
47
                 ...state,
47
                 ...state,
48
                 connectionOptions: {
48
                 connectionOptions: {
49
-                    ...(state.connectionOptions || {}),
49
+                    ...state.connectionOptions,
50
                     ...buildConnectionOptions(action.domain)
50
                     ...buildConnectionOptions(action.domain)
51
                 }
51
                 }
52
             };
52
             };

+ 46
- 19
react/features/base/participants/reducer.js View File

25
  * @property {boolean} local - If true, participant is local.
25
  * @property {boolean} local - If true, participant is local.
26
  * @property {boolean} pinned - If true, participant is currently a
26
  * @property {boolean} pinned - If true, participant is currently a
27
  * "PINNED_ENDPOINT".
27
  * "PINNED_ENDPOINT".
28
- * @property {boolean} speaking - If true, participant is currently a dominant
29
- * speaker.
28
+ * @property {boolean} dominantSpeaker - If this participant is the dominant
29
+ * speaker in the (associated) conference, <tt>true</tt>; otherwise,
30
+ * <tt>false</tt>.
30
  * @property {string} email - Participant email.
31
  * @property {string} email - Participant email.
31
  */
32
  */
32
 
33
 
36
  * @type {string[]}
37
  * @type {string[]}
37
  */
38
  */
38
 const PARTICIPANT_PROPS_TO_OMIT_WHEN_UPDATE
39
 const PARTICIPANT_PROPS_TO_OMIT_WHEN_UPDATE
39
-    = [ 'id', 'local', 'pinned', 'speaking' ];
40
+    = [ 'dominantSpeaker', 'id', 'local', 'pinned' ];
40
 
41
 
41
 /**
42
 /**
42
  * Reducer function for a single participant.
43
  * Reducer function for a single participant.
53
     switch (action.type) {
54
     switch (action.type) {
54
     case DOMINANT_SPEAKER_CHANGED:
55
     case DOMINANT_SPEAKER_CHANGED:
55
         // Only one dominant speaker is allowed.
56
         // Only one dominant speaker is allowed.
56
-        return {
57
-            ...state,
58
-            speaking: state.id === action.participant.id
59
-        };
57
+        return (
58
+            _setStateProperty(
59
+                    state,
60
+                    'dominantSpeaker',
61
+                    state.id === action.participant.id));
60
 
62
 
61
     case PARTICIPANT_ID_CHANGED:
63
     case PARTICIPANT_ID_CHANGED:
62
         if (state.id === action.oldValue) {
64
         if (state.id === action.oldValue) {
68
                 avatar: state.avatar || _getAvatarURL(id, state.email)
70
                 avatar: state.avatar || _getAvatarURL(id, state.email)
69
             };
71
             };
70
         }
72
         }
71
-
72
-        return state;
73
+        break;
73
 
74
 
74
     case PARTICIPANT_JOINED: {
75
     case PARTICIPANT_JOINED: {
75
         const participant = action.participant; // eslint-disable-line no-shadow
76
         const participant = action.participant; // eslint-disable-line no-shadow
94
             name,
95
             name,
95
             pinned: participant.pinned || false,
96
             pinned: participant.pinned || false,
96
             role: participant.role || PARTICIPANT_ROLE.NONE,
97
             role: participant.role || PARTICIPANT_ROLE.NONE,
97
-            speaking: participant.speaking || false
98
+            dominantSpeaker: participant.dominantSpeaker || false
98
         };
99
         };
99
     }
100
     }
100
 
101
 
117
 
118
 
118
             return newState;
119
             return newState;
119
         }
120
         }
120
-
121
-        return state;
121
+        break;
122
 
122
 
123
     case PIN_PARTICIPANT:
123
     case PIN_PARTICIPANT:
124
         // Currently, only one pinned participant is allowed.
124
         // Currently, only one pinned participant is allowed.
125
-        return {
126
-            ...state,
127
-            pinned: state.id === action.participant.id
128
-        };
129
-
130
-    default:
131
-        return state;
125
+        return (
126
+            _setStateProperty(
127
+                    state,
128
+                    'pinned',
129
+                    state.id === action.participant.id));
132
     }
130
     }
131
+
132
+    return state;
133
 }
133
 }
134
 
134
 
135
 /**
135
 /**
201
 
201
 
202
     return urlPref + avatarId + urlSuf;
202
     return urlPref + avatarId + urlSuf;
203
 }
203
 }
204
+
205
+/**
206
+ * Sets a specific property of a specific state to a specific value. Prevents
207
+ * unnecessary state changes (when the specified <tt>value</tt> is equal to the
208
+ * value of the specified <tt>property</tt> of the specified <tt>state</tt>).
209
+ *
210
+ * @param {Object} state - The (Redux) state from which a new state is to be
211
+ * constructed by setting the specified <tt>property</tt> to the specified
212
+ * <tt>value</tt>.
213
+ * @param {string} property - The property of <tt>state</tt> which is to be
214
+ * assigned the specified <tt>value</tt> (in the new state).
215
+ * @param {*} value - The value to assign to the specified <tt>property</tt>.
216
+ * @returns {Object} The specified <tt>state</tt> if the value of the specified
217
+ * <tt>property</tt> equals the specified <tt>value/tt>; otherwise, a new state
218
+ * constructed from the specified <tt>state</tt> by setting the specified
219
+ * <tt>property</tt> to the specified <tt>value</tt>.
220
+ */
221
+function _setStateProperty(state, property, value) {
222
+    if (state[property] !== value) {
223
+        return {
224
+            ...state,
225
+            [property]: value
226
+        };
227
+    }
228
+
229
+    return state;
230
+}

+ 4
- 3
react/features/filmStrip/components/Thumbnail.js View File

81
         //    participants would be hearing themselves.
81
         //    participants would be hearing themselves.
82
         const audioMuted = !audioTrack || audioTrack.muted;
82
         const audioMuted = !audioTrack || audioTrack.muted;
83
         const renderAudio = !audioMuted && !audioTrack.local;
83
         const renderAudio = !audioMuted && !audioTrack.local;
84
+        const participantId = participant.id;
84
         const participantNotInLargeVideo
85
         const participantNotInLargeVideo
85
-            = participant.id !== largeVideo.participantId;
86
+            = participantId !== largeVideo.participantId;
86
         const videoMuted = !videoTrack || videoTrack.muted;
87
         const videoMuted = !videoTrack || videoTrack.muted;
87
 
88
 
88
         return (
89
         return (
96
                             = { audioTrack.jitsiTrack.getOriginalStream() } /> }
97
                             = { audioTrack.jitsiTrack.getOriginalStream() } /> }
97
 
98
 
98
                 <ParticipantView
99
                 <ParticipantView
99
-                    participantId = { participant.id }
100
+                    participantId = { participantId }
100
                     showAvatar = { participantNotInLargeVideo }
101
                     showAvatar = { participantNotInLargeVideo }
101
                     showVideo = { participantNotInLargeVideo }
102
                     showVideo = { participantNotInLargeVideo }
102
                     zOrder = { 1 } />
103
                     zOrder = { 1 } />
104
                 { participant.role === PARTICIPANT_ROLE.MODERATOR
105
                 { participant.role === PARTICIPANT_ROLE.MODERATOR
105
                     && <ModeratorIndicator /> }
106
                     && <ModeratorIndicator /> }
106
 
107
 
107
-                { participant.speaking
108
+                { participant.dominantSpeaker
108
                     && <DominantSpeakerIndicator /> }
109
                     && <DominantSpeakerIndicator /> }
109
 
110
 
110
                 { audioMuted
111
                 { audioMuted

+ 36
- 38
react/features/largeVideo/actions.js View File

26
             const largeVideo = state['features/largeVideo'];
26
             const largeVideo = state['features/largeVideo'];
27
             const tracks = state['features/base/tracks'];
27
             const tracks = state['features/base/tracks'];
28
 
28
 
29
-            const videoTrack = getTrackByMediaTypeAndParticipant(
30
-                tracks, MEDIA_TYPE.VIDEO, largeVideo.participantId);
29
+            const id = largeVideo.participantId;
30
+            const videoTrack
31
+                = getTrackByMediaTypeAndParticipant(
32
+                        tracks,
33
+                        MEDIA_TYPE.VIDEO,
34
+                        id);
31
 
35
 
32
             try {
36
             try {
33
                 conference.selectParticipant(
37
                 conference.selectParticipant(
34
-                    videoTrack && videoTrack.videoType === VIDEO_TYPE.CAMERA
35
-                        ? largeVideo.participantId
36
-                        : null);
38
+                        videoTrack && videoTrack.videoType === VIDEO_TYPE.CAMERA
39
+                            ? id
40
+                            : null);
37
             } catch (err) {
41
             } catch (err) {
38
                 _handleParticipantError(err);
42
                 _handleParticipantError(err);
39
             }
43
             }
51
 export function selectParticipantInLargeVideo() {
55
 export function selectParticipantInLargeVideo() {
52
     return (dispatch, getState) => {
56
     return (dispatch, getState) => {
53
         const state = getState();
57
         const state = getState();
54
-        const participants = state['features/base/participants'];
55
-        const tracks = state['features/base/tracks'];
58
+        const participantId = _electParticipantInLargeVideo(state);
56
         const largeVideo = state['features/largeVideo'];
59
         const largeVideo = state['features/largeVideo'];
57
-        const participantId
58
-            = _electParticipantInLargeVideo(participants, tracks);
59
 
60
 
60
         if (participantId !== largeVideo.participantId) {
61
         if (participantId !== largeVideo.participantId) {
61
             dispatch({
62
             dispatch({
77
  * @returns {(Track|undefined)}
78
  * @returns {(Track|undefined)}
78
  */
79
  */
79
 function _electLastVisibleVideo(tracks) {
80
 function _electLastVisibleVideo(tracks) {
80
-    let videoTrack;
81
-
82
     // First we try to get most recent remote video track.
81
     // First we try to get most recent remote video track.
83
-    for (let i = tracks.length - 1; i >= 0; i--) {
84
-        if (tracks[i].mediaType === MEDIA_TYPE.VIDEO && !tracks[i].local) {
85
-            videoTrack = tracks[i];
86
-            break;
82
+    for (let i = tracks.length - 1; i >= 0; --i) {
83
+        const track = tracks[i];
84
+
85
+        if (!track.local && track.mediaType === MEDIA_TYPE.VIDEO) {
86
+            return track;
87
         }
87
         }
88
     }
88
     }
89
 
89
 
90
     // And if no remote video tracks are available, we select the local one.
90
     // And if no remote video tracks are available, we select the local one.
91
-    if (!videoTrack) {
92
-        videoTrack = getLocalVideoTrack(tracks);
93
-    }
94
-
95
-    return videoTrack;
91
+    return getLocalVideoTrack(tracks);
96
 }
92
 }
97
 
93
 
98
 /**
94
 /**
99
- * Returns the participant ID who is to be on the stage i.e. should be displayed
100
- * in LargeVideo.
95
+ * Returns the identifier of the participant who is to be on the stage i.e.
96
+ * should be displayed in <tt>LargeVideo</tt>.
101
  *
97
  *
102
- * @param {Participant[]} participants - All participants.
103
- * @param {Track[]} tracks - All tracks.
98
+ * @param {Object} state - The Redux state from which the participant to be
99
+ * displayed in <tt>LargeVideo</tt> is to be elected.
104
  * @private
100
  * @private
105
  * @returns {(string|undefined)}
101
  * @returns {(string|undefined)}
106
  */
102
  */
107
-function _electParticipantInLargeVideo(participants, tracks) {
108
-    // First get the pinned participant. If local participant is pinned, he will
109
-    // be shown in LargeVideo.
103
+function _electParticipantInLargeVideo(state) {
104
+    // First get the pinned participant. If the local participant is pinned,
105
+    // he/she will be shown in LargeVideo.
106
+    const participants = state['features/base/participants'];
110
     let participant = participants.find(p => p.pinned);
107
     let participant = participants.find(p => p.pinned);
111
     let id = participant ? participant.id : undefined;
108
     let id = participant ? participant.id : undefined;
112
 
109
 
113
-    // If no participant is pinned, get the dominant speaker. But local
114
-    // participant won't be displayed in LargeVideo even if he is the dominant
115
-    // speaker.
116
     if (!id) {
110
     if (!id) {
117
-        participant = participants.find(p => p.speaking && !p.local);
111
+        // No participant is pinned so get the dominant speaker. But the local
112
+        // participant won't be displayed in LargeVideo even if he/she is the
113
+        // dominant speaker.
114
+        participant = participants.find(p => p.dominantSpeaker && !p.local);
118
         if (participant) {
115
         if (participant) {
119
             id = participant.id;
116
             id = participant.id;
120
         }
117
         }
121
-    }
122
 
118
 
123
-    // If no participant is pinned and no dominant speaker, just get the
124
-    // participant with last visible video track. This may turn out to be local
125
-    // participant.
126
-    if (!id) {
127
-        const videoTrack = _electLastVisibleVideo(tracks);
119
+        if (!id) {
120
+            // There is no dominant speaker so get the participant with the last
121
+            // visible video track. This may turn out to be the local
122
+            // participant.
123
+            const tracks = state['features/base/tracks'];
124
+            const videoTrack = _electLastVisibleVideo(tracks);
128
 
125
 
129
-        id = videoTrack && videoTrack.participantId;
126
+            id = videoTrack && videoTrack.participantId;
127
+        }
130
     }
128
     }
131
 
129
 
132
     return id;
130
     return id;

+ 3
- 5
react/features/largeVideo/reducer.js View File

24
                     participantId: action.newValue
24
                     participantId: action.newValue
25
                 };
25
                 };
26
             }
26
             }
27
-
28
-            return state;
27
+            break;
29
 
28
 
30
         case LARGE_VIDEO_PARTICIPANT_CHANGED:
29
         case LARGE_VIDEO_PARTICIPANT_CHANGED:
31
             return {
30
             return {
32
                 ...state,
31
                 ...state,
33
                 participantId: action.participantId
32
                 participantId: action.participantId
34
             };
33
             };
35
-
36
-        default:
37
-            return state;
38
         }
34
         }
35
+
36
+        return state;
39
     });
37
     });

Loading…
Cancel
Save