Browse Source

Reduce the number of unnecessary Redux state changes

j8
Lyubomir Marinov 8 years ago
parent
commit
4d335e086b

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

@@ -46,7 +46,7 @@ ReducerRegistry.register('features/base/connection',
46 46
             return {
47 47
                 ...state,
48 48
                 connectionOptions: {
49
-                    ...(state.connectionOptions || {}),
49
+                    ...state.connectionOptions,
50 50
                     ...buildConnectionOptions(action.domain)
51 51
                 }
52 52
             };

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

@@ -25,8 +25,9 @@ import {
25 25
  * @property {boolean} local - If true, participant is local.
26 26
  * @property {boolean} pinned - If true, participant is currently a
27 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 31
  * @property {string} email - Participant email.
31 32
  */
32 33
 
@@ -36,7 +37,7 @@ import {
36 37
  * @type {string[]}
37 38
  */
38 39
 const PARTICIPANT_PROPS_TO_OMIT_WHEN_UPDATE
39
-    = [ 'id', 'local', 'pinned', 'speaking' ];
40
+    = [ 'dominantSpeaker', 'id', 'local', 'pinned' ];
40 41
 
41 42
 /**
42 43
  * Reducer function for a single participant.
@@ -53,10 +54,11 @@ function participant(state, action) {
53 54
     switch (action.type) {
54 55
     case DOMINANT_SPEAKER_CHANGED:
55 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 63
     case PARTICIPANT_ID_CHANGED:
62 64
         if (state.id === action.oldValue) {
@@ -68,8 +70,7 @@ function participant(state, action) {
68 70
                 avatar: state.avatar || _getAvatarURL(id, state.email)
69 71
             };
70 72
         }
71
-
72
-        return state;
73
+        break;
73 74
 
74 75
     case PARTICIPANT_JOINED: {
75 76
         const participant = action.participant; // eslint-disable-line no-shadow
@@ -94,7 +95,7 @@ function participant(state, action) {
94 95
             name,
95 96
             pinned: participant.pinned || false,
96 97
             role: participant.role || PARTICIPANT_ROLE.NONE,
97
-            speaking: participant.speaking || false
98
+            dominantSpeaker: participant.dominantSpeaker || false
98 99
         };
99 100
     }
100 101
 
@@ -117,19 +118,18 @@ function participant(state, action) {
117 118
 
118 119
             return newState;
119 120
         }
120
-
121
-        return state;
121
+        break;
122 122
 
123 123
     case PIN_PARTICIPANT:
124 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,3 +201,30 @@ function _getAvatarURL(participantId, email) {
201 201
 
202 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,8 +81,9 @@ class Thumbnail extends Component {
81 81
         //    participants would be hearing themselves.
82 82
         const audioMuted = !audioTrack || audioTrack.muted;
83 83
         const renderAudio = !audioMuted && !audioTrack.local;
84
+        const participantId = participant.id;
84 85
         const participantNotInLargeVideo
85
-            = participant.id !== largeVideo.participantId;
86
+            = participantId !== largeVideo.participantId;
86 87
         const videoMuted = !videoTrack || videoTrack.muted;
87 88
 
88 89
         return (
@@ -96,7 +97,7 @@ class Thumbnail extends Component {
96 97
                             = { audioTrack.jitsiTrack.getOriginalStream() } /> }
97 98
 
98 99
                 <ParticipantView
99
-                    participantId = { participant.id }
100
+                    participantId = { participantId }
100 101
                     showAvatar = { participantNotInLargeVideo }
101 102
                     showVideo = { participantNotInLargeVideo }
102 103
                     zOrder = { 1 } />
@@ -104,7 +105,7 @@ class Thumbnail extends Component {
104 105
                 { participant.role === PARTICIPANT_ROLE.MODERATOR
105 106
                     && <ModeratorIndicator /> }
106 107
 
107
-                { participant.speaking
108
+                { participant.dominantSpeaker
108 109
                     && <DominantSpeakerIndicator /> }
109 110
 
110 111
                 { audioMuted

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

@@ -26,14 +26,18 @@ export function selectParticipant() {
26 26
             const largeVideo = state['features/largeVideo'];
27 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 36
             try {
33 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 41
             } catch (err) {
38 42
                 _handleParticipantError(err);
39 43
             }
@@ -51,11 +55,8 @@ export function selectParticipant() {
51 55
 export function selectParticipantInLargeVideo() {
52 56
     return (dispatch, getState) => {
53 57
         const state = getState();
54
-        const participants = state['features/base/participants'];
55
-        const tracks = state['features/base/tracks'];
58
+        const participantId = _electParticipantInLargeVideo(state);
56 59
         const largeVideo = state['features/largeVideo'];
57
-        const participantId
58
-            = _electParticipantInLargeVideo(participants, tracks);
59 60
 
60 61
         if (participantId !== largeVideo.participantId) {
61 62
             dispatch({
@@ -77,56 +78,53 @@ export function selectParticipantInLargeVideo() {
77 78
  * @returns {(Track|undefined)}
78 79
  */
79 80
 function _electLastVisibleVideo(tracks) {
80
-    let videoTrack;
81
-
82 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 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 100
  * @private
105 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 107
     let participant = participants.find(p => p.pinned);
111 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 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 115
         if (participant) {
119 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 130
     return id;

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

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

Loading…
Cancel
Save