瀏覽代碼

ref(1-on-1): move remote video visibility to a selector (#1922)

* ref(1-on-1): move remote visibility to a selector

Derive whether or not remote videos should display using a selector
to look across different states. A selector was chosen over using
memoized selectors (reselect) or subscribers as a first step
approach, avoiding additional mutations caused by a subscriber
updating the filmstrip state and avoiding additional api overhead
introduced by reselect.

* rename selector
master
virtuacoplenny 7 年之前
父節點
當前提交
ef1b8fdb77

+ 1
- 29
conference.js 查看文件

67
 import { statsEmitter } from './react/features/connection-indicator';
67
 import { statsEmitter } from './react/features/connection-indicator';
68
 import { showDesktopPicker } from  './react/features/desktop-picker';
68
 import { showDesktopPicker } from  './react/features/desktop-picker';
69
 import { maybeOpenFeedbackDialog } from './react/features/feedback';
69
 import { maybeOpenFeedbackDialog } from './react/features/feedback';
70
-import { setFilmstripRemoteVideosVisibility } from './react/features/filmstrip';
71
 import {
70
 import {
72
     mediaPermissionPromptVisibilityChanged,
71
     mediaPermissionPromptVisibilityChanged,
73
     suspendDetected
72
     suspendDetected
1626
 
1625
 
1627
             // check the roles for the new user and reflect them
1626
             // check the roles for the new user and reflect them
1628
             APP.UI.updateUserRole(user);
1627
             APP.UI.updateUserRole(user);
1629
-
1630
-            updateRemoteThumbnailsVisibility();
1631
         });
1628
         });
1629
+
1632
         room.on(ConferenceEvents.USER_LEFT, (id, user) => {
1630
         room.on(ConferenceEvents.USER_LEFT, (id, user) => {
1633
             APP.store.dispatch(participantLeft(id, user));
1631
             APP.store.dispatch(participantLeft(id, user));
1634
             logger.log('USER %s LEFT', id, user);
1632
             logger.log('USER %s LEFT', id, user);
1635
             APP.API.notifyUserLeft(id);
1633
             APP.API.notifyUserLeft(id);
1636
             APP.UI.removeUser(id, user.getDisplayName());
1634
             APP.UI.removeUser(id, user.getDisplayName());
1637
             APP.UI.onSharedVideoStop(id);
1635
             APP.UI.onSharedVideoStop(id);
1638
-
1639
-            updateRemoteThumbnailsVisibility();
1640
         });
1636
         });
1641
 
1637
 
1642
         room.on(ConferenceEvents.USER_STATUS_CHANGED, (id, status) => {
1638
         room.on(ConferenceEvents.USER_STATUS_CHANGED, (id, status) => {
1780
             APP.UI.addListener(
1776
             APP.UI.addListener(
1781
                 UIEvents.VIDEO_UNMUTING_WHILE_AUDIO_ONLY,
1777
                 UIEvents.VIDEO_UNMUTING_WHILE_AUDIO_ONLY,
1782
                 () => this._displayAudioOnlyTooltip('videoMute'));
1778
                 () => this._displayAudioOnlyTooltip('videoMute'));
1783
-
1784
-            APP.UI.addListener(
1785
-                UIEvents.PINNED_ENDPOINT,
1786
-                updateRemoteThumbnailsVisibility);
1787
         }
1779
         }
1788
 
1780
 
1789
         room.on(ConferenceEvents.CONNECTION_INTERRUPTED, () => {
1781
         room.on(ConferenceEvents.CONNECTION_INTERRUPTED, () => {
2147
                     }
2139
                     }
2148
                 });
2140
                 });
2149
             }
2141
             }
2150
-
2151
-            updateRemoteThumbnailsVisibility();
2152
         });
2142
         });
2153
         room.addCommandListener(
2143
         room.addCommandListener(
2154
             this.commands.defaults.SHARED_VIDEO, ({value, attributes}, id) => {
2144
             this.commands.defaults.SHARED_VIDEO, ({value, attributes}, id) => {
2164
                     APP.UI.onSharedVideoUpdate(id, value, attributes);
2154
                     APP.UI.onSharedVideoUpdate(id, value, attributes);
2165
                 }
2155
                 }
2166
             });
2156
             });
2167
-
2168
-        function updateRemoteThumbnailsVisibility() {
2169
-            const localUserId = APP.conference.getMyUserId();
2170
-            const remoteParticipantsCount = room.getParticipantCount() - 1;
2171
-
2172
-            // Get the remote thumbnail count for cases where there are
2173
-            // non-participants displaying video, such as with video sharing.
2174
-            const remoteVideosCount = APP.UI.getRemoteVideosCount();
2175
-
2176
-            const shouldShowRemoteThumbnails = interfaceConfig.filmStripOnly
2177
-                || (APP.UI.isPinned(localUserId) && remoteVideosCount)
2178
-                || remoteVideosCount > 1
2179
-                || remoteParticipantsCount !== remoteVideosCount;
2180
-
2181
-            APP.store.dispatch(
2182
-                setFilmstripRemoteVideosVisibility(
2183
-                    Boolean(shouldShowRemoteThumbnails)));
2184
-        }
2185
     },
2157
     },
2186
     /**
2158
     /**
2187
     * Adds any room listener.
2159
     * Adds any room listener.

+ 0
- 12
react/features/filmstrip/actionTypes.js 查看文件

1
-/**
2
- * The type of action which signals to change the visibility of remote videos in
3
- * the filmstrip.
4
- *
5
- * {
6
- *     type: SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY,
7
- *     remoteVideosVisible: boolean
8
- * }
9
- */
10
-export const SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY
11
-    = Symbol('SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY');
12
-
13
 /**
1
 /**
14
  * The type of action sets the visibility of the entire filmstrip;
2
  * The type of action sets the visibility of the entire filmstrip;
15
  *
3
  *

+ 0
- 18
react/features/filmstrip/actions.js 查看文件

1
 import {
1
 import {
2
-    SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY,
3
     SET_FILMSTRIP_VISIBILITY
2
     SET_FILMSTRIP_VISIBILITY
4
 } from './actionTypes';
3
 } from './actionTypes';
5
 
4
 
6
-/**
7
- * Sets the visibility of remote videos in the filmstrip.
8
- *
9
- * @param {boolean} remoteVideosVisible - Whether or not remote videos in the
10
- * filmstrip should be visible.
11
- * @returns {{
12
- *     type: SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY,
13
- *     remoteVideosVisible: boolean
14
- * }}
15
- */
16
-export function setFilmstripRemoteVideosVisibility(remoteVideosVisible) {
17
-    return {
18
-        type: SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY,
19
-        remoteVideosVisible
20
-    };
21
-}
22
-
23
 /**
5
 /**
24
  * Sets if the entire filmstrip should be visible.
6
  * Sets if the entire filmstrip should be visible.
25
  *
7
  *

+ 3
- 4
react/features/filmstrip/components/Filmstrip.web.js 查看文件

5
 
5
 
6
 import { Toolbox } from '../../toolbox';
6
 import { Toolbox } from '../../toolbox';
7
 
7
 
8
+import { shouldRemoteVideosBeVisible } from '../functions';
9
+
8
 /**
10
 /**
9
  * Implements a React {@link Component} which represents the filmstrip on
11
  * Implements a React {@link Component} which represents the filmstrip on
10
  * Web/React.
12
  * Web/React.
89
  * }}
91
  * }}
90
  */
92
  */
91
 function _mapStateToProps(state) {
93
 function _mapStateToProps(state) {
92
-    const { remoteVideosVisible } = state['features/filmstrip'];
93
-    const { disable1On1Mode } = state['features/base/config'];
94
-
95
     return {
94
     return {
96
-        _remoteVideosVisible: Boolean(remoteVideosVisible || disable1On1Mode)
95
+        _remoteVideosVisible: shouldRemoteVideosBeVisible(state)
97
     };
96
     };
98
 }
97
 }
99
 
98
 

+ 34
- 0
react/features/filmstrip/functions.js 查看文件

1
+declare var interfaceConfig: Object;
2
+
3
+import {
4
+    getPinnedParticipant,
5
+    getLocalParticipant
6
+} from '../base/participants';
7
+
8
+/**
9
+ * A selector for determining whether or not remote video thumbnails should be
10
+ * displayed in the filmstrip.
11
+ *
12
+ * @param {Object} state - The full redux state.
13
+ * @returns {boolean} - True if remote video thumbnails should be displayed.
14
+ */
15
+export function shouldRemoteVideosBeVisible(state) {
16
+    const participants = state['features/base/participants'];
17
+
18
+    const shouldShowVideos
19
+        = state['features/base/config'].disable1On1Mode
20
+
21
+        || interfaceConfig.filmStripOnly
22
+
23
+        // This is not a 1-on-1 call.
24
+        || participants.length > 2
25
+
26
+        // There is another participant and the local participant is pinned.
27
+        || (participants.length > 1
28
+            && getLocalParticipant(state) === getPinnedParticipant(state))
29
+
30
+        // There is any non-person participant, like a shared video.
31
+        || participants.find(participant => participant.isBot);
32
+
33
+    return Boolean(shouldShowVideos);
34
+}

+ 1
- 0
react/features/filmstrip/index.js 查看文件

1
 export * from './actions';
1
 export * from './actions';
2
 export * from './actionTypes';
2
 export * from './actionTypes';
3
 export * from './components';
3
 export * from './components';
4
+export * from './functions';
4
 
5
 
5
 import './middleware';
6
 import './middleware';
6
 import './reducer';
7
 import './reducer';

+ 0
- 12
react/features/filmstrip/reducer.js 查看文件

1
 import { ReducerRegistry } from '../base/redux';
1
 import { ReducerRegistry } from '../base/redux';
2
 import {
2
 import {
3
-    SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY,
4
     SET_FILMSTRIP_VISIBILITY
3
     SET_FILMSTRIP_VISIBILITY
5
 } from './actionTypes';
4
 } from './actionTypes';
6
 
5
 
7
 const DEFAULT_STATE = {
6
 const DEFAULT_STATE = {
8
-    /**
9
-     * By default start with remote videos hidden for 1-on-1 mode and rely on
10
-     * other logic to invoke an action to make them visible when needed.
11
-     */
12
-    remoteVideosVisible: false,
13
-
14
     visible: true
7
     visible: true
15
 };
8
 };
16
 
9
 
18
     'features/filmstrip',
11
     'features/filmstrip',
19
     (state = DEFAULT_STATE, action) => {
12
     (state = DEFAULT_STATE, action) => {
20
         switch (action.type) {
13
         switch (action.type) {
21
-        case SET_FILMSTRIP_REMOTE_VIDEOS_VISIBLITY:
22
-            return {
23
-                ...state,
24
-                remoteVideosVisible: action.remoteVideosVisible
25
-            };
26
         case SET_FILMSTRIP_VISIBILITY:
14
         case SET_FILMSTRIP_VISIBILITY:
27
             return {
15
             return {
28
                 ...state,
16
                 ...state,

+ 3
- 2
react/features/recording/components/RecordingLabel.web.js 查看文件

2
 import { connect } from 'react-redux';
2
 import { connect } from 'react-redux';
3
 
3
 
4
 import { translate } from '../../base/i18n';
4
 import { translate } from '../../base/i18n';
5
+import { shouldRemoteVideosBeVisible } from '../../filmstrip';
5
 
6
 
6
 /**
7
 /**
7
  * Implements a React {@link Component} which displays the current state of
8
  * Implements a React {@link Component} which displays the current state of
140
  * }}
141
  * }}
141
  */
142
  */
142
 function _mapStateToProps(state) {
143
 function _mapStateToProps(state) {
143
-    const { remoteVideosVisible, visible } = state['features/filmstrip'];
144
+    const { visible } = state['features/filmstrip'];
144
     const { labelDisplayConfiguration } = state['features/recording'];
145
     const { labelDisplayConfiguration } = state['features/recording'];
145
 
146
 
146
     return {
147
     return {
164
          *
165
          *
165
          * @type {boolean}
166
          * @type {boolean}
166
          */
167
          */
167
-        _remoteVideosVisible: remoteVideosVisible
168
+        _remoteVideosVisible: shouldRemoteVideosBeVisible(state)
168
     };
169
     };
169
 }
170
 }
170
 
171
 

+ 6
- 13
react/features/video-quality/components/VideoQualityLabel.web.js 查看文件

3
 
3
 
4
 import { translate } from '../../base/i18n';
4
 import { translate } from '../../base/i18n';
5
 import { Popover } from '../../base/popover';
5
 import { Popover } from '../../base/popover';
6
+import { shouldRemoteVideosBeVisible } from '../../filmstrip';
7
+
6
 import { VideoQualityDialog } from './';
8
 import { VideoQualityDialog } from './';
7
 
9
 
8
 import {
10
 import {
209
  * }}
211
  * }}
210
  */
212
  */
211
 function _mapStateToProps(state) {
213
 function _mapStateToProps(state) {
212
-    const {
213
-        audioOnly,
214
-        conference
215
-    } = state['features/base/conference'];
216
-    const { disable1On1Mode } = state['features/base/config'];
217
-    const {
218
-        remoteVideosVisible,
219
-        visible
220
-    } = state['features/filmstrip'];
221
-    const {
222
-        resolution
223
-    } = state['features/large-video'];
214
+    const { audioOnly, conference } = state['features/base/conference'];
215
+    const { visible } = state['features/filmstrip'];
216
+    const { resolution } = state['features/large-video'];
224
 
217
 
225
     return {
218
     return {
226
         _audioOnly: audioOnly,
219
         _audioOnly: audioOnly,
227
         _conferenceStarted: Boolean(conference),
220
         _conferenceStarted: Boolean(conference),
228
         _filmstripVisible: visible,
221
         _filmstripVisible: visible,
229
-        _remoteVideosVisible: Boolean(remoteVideosVisible || disable1On1Mode),
222
+        _remoteVideosVisible: shouldRemoteVideosBeVisible(state),
230
         _resolution: resolution
223
         _resolution: resolution
231
     };
224
     };
232
 }
225
 }

Loading…
取消
儲存