Explorar el Código

fix(context-menus) Fix participant context menus/toolbar overflow menu

- on ipads, long touch open dialog now opens the context menu to the left of the thumbnail as expected
- on ipads, now we close context menus on tap out
- fix case when participant context menu's height > tileview videos' height causing scroll on videos pane
- keep toolbox open while the overflow menu is shown
- keep remote participant video thumbnail in filmstrip visible even if toolbox is hidden, if context menu is opened
- Fix bug where toolbox could be completely disabled
master
Horatiu Muresan hace 4 años
padre
commit
b801e0115d
No account linked to committer's email address

+ 9
- 0
react/features/base/connection/actionTypes.js Ver fichero

54
  */
54
  */
55
 export const SET_LOCATION_URL = 'SET_LOCATION_URL';
55
 export const SET_LOCATION_URL = 'SET_LOCATION_URL';
56
 
56
 
57
+/**
58
+ * The type of (redux) action which tells whether connection info should be displayed
59
+ * on context menu.
60
+ *
61
+ * {
62
+ *     type: SHOW_CONNECTION_INFO,
63
+ *     showConnectionInfo: boolean
64
+ * }
65
+ */
57
 export const SHOW_CONNECTION_INFO = 'SHOW_CONNECTION_INFO';
66
 export const SHOW_CONNECTION_INFO = 'SHOW_CONNECTION_INFO';

+ 51
- 3
react/features/base/popover/components/Popover.web.js Ver fichero

113
         id: ''
113
         id: ''
114
     };
114
     };
115
 
115
 
116
+    /**
117
+     * Reference to the dialog container.
118
+     */
119
+    _containerRef: Object;
120
+
121
+
116
     /**
122
     /**
117
      * Initializes a new {@code Popover} instance.
123
      * Initializes a new {@code Popover} instance.
118
      *
124
      *
130
         this._onHideDialog = this._onHideDialog.bind(this);
136
         this._onHideDialog = this._onHideDialog.bind(this);
131
         this._onShowDialog = this._onShowDialog.bind(this);
137
         this._onShowDialog = this._onShowDialog.bind(this);
132
         this._onKeyPress = this._onKeyPress.bind(this);
138
         this._onKeyPress = this._onKeyPress.bind(this);
139
+        this._containerRef = React.createRef();
133
         this._onEscKey = this._onEscKey.bind(this);
140
         this._onEscKey = this._onEscKey.bind(this);
134
         this._onThumbClick = this._onThumbClick.bind(this);
141
         this._onThumbClick = this._onThumbClick.bind(this);
142
+        this._onTouchStart = this._onTouchStart.bind(this);
135
     }
143
     }
136
 
144
 
137
     /**
145
     /**
141
      * @public
149
      * @public
142
      */
150
      */
143
     showDialog() {
151
     showDialog() {
144
-        this.setState({ showDialog: true });
152
+        this._onShowDialog();
153
+    }
154
+
155
+    /**
156
+     * Sets up a touch event listener to attach.
157
+     *
158
+     * @inheritdoc
159
+     * @returns {void}
160
+     */
161
+    componentDidMount() {
162
+        window.addEventListener('touchstart', this._onTouchStart);
163
+    }
164
+
165
+    /**
166
+     * Removes the listener set up in the {@code componentDidMount} method.
167
+     *
168
+     * @inheritdoc
169
+     * @returns {void}
170
+     */
171
+    componentWillUnmount() {
172
+        window.removeEventListener('touchstart', this._onTouchStart);
145
     }
173
     }
146
 
174
 
147
     /**
175
     /**
178
                 onClick = { this._onThumbClick }
206
                 onClick = { this._onThumbClick }
179
                 onKeyPress = { this._onKeyPress }
207
                 onKeyPress = { this._onKeyPress }
180
                 onMouseEnter = { this._onShowDialog }
208
                 onMouseEnter = { this._onShowDialog }
181
-                onMouseLeave = { this._onHideDialog }>
209
+                onMouseLeave = { this._onHideDialog }
210
+                ref = { this._containerRef }>
182
                 <InlineDialog
211
                 <InlineDialog
183
                     content = { this._renderContent() }
212
                     content = { this._renderContent() }
184
                     isOpen = { this.state.showDialog }
213
                     isOpen = { this.state.showDialog }
189
         );
218
         );
190
     }
219
     }
191
 
220
 
221
+    _onTouchStart: (event: TouchEvent) => void;
222
+
223
+    /**
224
+     * Hide dialog on touch outside of the context menu.
225
+     *
226
+     * @param {TouchEvent} event - The touch event.
227
+     * @private
228
+     * @returns {void}
229
+     */
230
+    _onTouchStart(event) {
231
+        if (this.state.showDialog
232
+            && !this.props.overflowDrawer
233
+            && this._containerRef
234
+            && this._containerRef.current
235
+            && !this._containerRef.current.contains(event.target)) {
236
+            this._onHideDialog();
237
+        }
238
+    }
239
+
192
     _onHideDialog: () => void;
240
     _onHideDialog: () => void;
193
 
241
 
194
     /**
242
     /**
216
      * @returns {void}
264
      * @returns {void}
217
      */
265
      */
218
     _onShowDialog(event) {
266
     _onShowDialog(event) {
219
-        event.stopPropagation();
267
+        event && event.stopPropagation();
220
         if (!this.props.disablePopover) {
268
         if (!this.props.disablePopover) {
221
             this.setState({ showDialog: true });
269
             this.setState({ showDialog: true });
222
 
270
 

+ 12
- 0
react/features/base/responsive-ui/actionTypes.js Ver fichero

30
  * @public
30
  * @public
31
  */
31
  */
32
 export const SET_REDUCED_UI = 'SET_REDUCED_UI';
32
 export const SET_REDUCED_UI = 'SET_REDUCED_UI';
33
+
34
+/**
35
+ * The type of (redux) action which tells whether a local or remote participant
36
+ * context menu is open.
37
+ *
38
+ * {
39
+ *     type: SET_CONTEXT_MENU_OPEN,
40
+ *     showConnectionInfo: boolean
41
+ * }
42
+ */
43
+export const SET_CONTEXT_MENU_OPEN = 'SET_CONTEXT_MENU_OPEN';
44
+

+ 14
- 1
react/features/base/responsive-ui/actions.js Ver fichero

7
 import { getParticipantsPaneOpen } from '../../participants-pane/functions';
7
 import { getParticipantsPaneOpen } from '../../participants-pane/functions';
8
 import theme from '../../participants-pane/theme.json';
8
 import theme from '../../participants-pane/theme.json';
9
 
9
 
10
-import { CLIENT_RESIZED, SET_ASPECT_RATIO, SET_REDUCED_UI } from './actionTypes';
10
+import { CLIENT_RESIZED, SET_ASPECT_RATIO, SET_CONTEXT_MENU_OPEN, SET_REDUCED_UI } from './actionTypes';
11
 import { ASPECT_RATIO_NARROW, ASPECT_RATIO_WIDE } from './constants';
11
 import { ASPECT_RATIO_NARROW, ASPECT_RATIO_WIDE } from './constants';
12
 
12
 
13
 /**
13
 /**
110
         }
110
         }
111
     };
111
     };
112
 }
112
 }
113
+
114
+/**
115
+ * Sets whether the local or remote participant context menu is open.
116
+ *
117
+ * @param {boolean} isOpen - Whether local or remote context menu is open.
118
+ * @returns {Object}
119
+ */
120
+export function setParticipantContextMenuOpen(isOpen: boolean) {
121
+    return {
122
+        type: SET_CONTEXT_MENU_OPEN,
123
+        isOpen
124
+    };
125
+}

+ 6
- 2
react/features/base/responsive-ui/reducer.js Ver fichero

2
 
2
 
3
 import { ReducerRegistry, set } from '../redux';
3
 import { ReducerRegistry, set } from '../redux';
4
 
4
 
5
-import { CLIENT_RESIZED, SET_ASPECT_RATIO, SET_REDUCED_UI } from './actionTypes';
5
+import { CLIENT_RESIZED, SET_ASPECT_RATIO, SET_CONTEXT_MENU_OPEN, SET_REDUCED_UI } from './actionTypes';
6
 import { ASPECT_RATIO_NARROW } from './constants';
6
 import { ASPECT_RATIO_NARROW } from './constants';
7
 
7
 
8
 const {
8
 const {
17
     aspectRatio: ASPECT_RATIO_NARROW,
17
     aspectRatio: ASPECT_RATIO_NARROW,
18
     clientHeight: innerHeight,
18
     clientHeight: innerHeight,
19
     clientWidth: innerWidth,
19
     clientWidth: innerWidth,
20
-    reducedUI: false
20
+    reducedUI: false,
21
+    contextMenuOpened: false
21
 };
22
 };
22
 
23
 
23
 ReducerRegistry.register('features/base/responsive-ui', (state = DEFAULT_STATE, action) => {
24
 ReducerRegistry.register('features/base/responsive-ui', (state = DEFAULT_STATE, action) => {
34
 
35
 
35
     case SET_REDUCED_UI:
36
     case SET_REDUCED_UI:
36
         return set(state, 'reducedUI', action.reducedUI);
37
         return set(state, 'reducedUI', action.reducedUI);
38
+
39
+    case SET_CONTEXT_MENU_OPEN:
40
+        return set(state, 'contextMenuOpened', action.isOpen);
37
     }
41
     }
38
 
42
 
39
     return state;
43
     return state;

+ 6
- 0
react/features/filmstrip/components/web/Filmstrip.js Ver fichero

34
 declare var APP: Object;
34
 declare var APP: Object;
35
 declare var interfaceConfig: Object;
35
 declare var interfaceConfig: Object;
36
 
36
 
37
+/**
38
+ * Fixes case in which context menu overflows and creates a scroll on the whole filmstrip videos pane.
39
+ */
40
+const TILEVIEW_VIDEO_PANES_STYLE = { overflow: 'visible' };
41
+
37
 /**
42
 /**
38
  * The type of the React {@code Component} props of {@link Filmstrip}.
43
  * The type of the React {@code Component} props of {@link Filmstrip}.
39
  */
44
  */
386
                     overscanRowCount = { 1 }
391
                     overscanRowCount = { 1 }
387
                     rowCount = { _rows }
392
                     rowCount = { _rows }
388
                     rowHeight = { _thumbnailHeight + TILE_VERTICAL_MARGIN }
393
                     rowHeight = { _thumbnailHeight + TILE_VERTICAL_MARGIN }
394
+                    style = { TILEVIEW_VIDEO_PANES_STYLE }
389
                     width = { _filmstripWidth }>
395
                     width = { _filmstripWidth }>
390
                     {
396
                     {
391
                         ThumbnailWrapper
397
                         ThumbnailWrapper

+ 3
- 1
react/features/filmstrip/functions.web.js Ver fichero

70
     const participantCount = getParticipantCountWithFake(state);
70
     const participantCount = getParticipantCountWithFake(state);
71
     let pinnedParticipant;
71
     let pinnedParticipant;
72
     const { disable1On1Mode } = state['features/base/config'];
72
     const { disable1On1Mode } = state['features/base/config'];
73
+    const { contextMenuOpened } = state['features/base/responsive-ui'];
73
 
74
 
74
     return Boolean(
75
     return Boolean(
75
-        participantCount > 2
76
+        contextMenuOpened
77
+            || participantCount > 2
76
 
78
 
77
             // Always show the filmstrip when there is another participant to
79
             // Always show the filmstrip when there is another participant to
78
             // show and the  local video is pinned, or the toolbar is displayed.
80
             // show and the  local video is pinned, or the toolbar is displayed.

+ 14
- 10
react/features/toolbox/actions.web.js Ver fichero

13
     clearToolboxTimeout,
13
     clearToolboxTimeout,
14
     setToolboxTimeout,
14
     setToolboxTimeout,
15
     setToolboxTimeoutMS,
15
     setToolboxTimeoutMS,
16
-    setToolboxVisible,
17
-    setToolboxEnabled
16
+    setToolboxVisible
18
 } from './actions.native';
17
 } from './actions.native';
19
 
18
 
20
 declare var interfaceConfig: Object;
19
 declare var interfaceConfig: Object;
132
             alwaysVisible,
131
             alwaysVisible,
133
             enabled,
132
             enabled,
134
             timeoutMS,
133
             timeoutMS,
135
-            visible
134
+            visible,
135
+            overflowDrawer
136
         } = state['features/toolbox'];
136
         } = state['features/toolbox'];
137
+        const { contextMenuOpened } = state['features/base/responsive-ui'];
138
+        const contextMenuOpenedInTileview = isLayoutTileView(state) && contextMenuOpened && !overflowDrawer;
137
 
139
 
138
-        if (enabled && !visible) {
140
+        if (enabled && !visible && !contextMenuOpenedInTileview) {
139
             dispatch(setToolboxVisible(true));
141
             dispatch(setToolboxVisible(true));
140
 
142
 
141
             // If the Toolbox is always visible, there's no need for a timeout
143
             // If the Toolbox is always visible, there's no need for a timeout
167
     };
169
     };
168
 }
170
 }
169
 
171
 
172
+
170
 /**
173
 /**
171
  * Disables and hides the toolbox on demand when in tile view.
174
  * Disables and hides the toolbox on demand when in tile view.
172
  *
175
  *
173
  * @returns {void}
176
  * @returns {void}
174
  */
177
  */
175
-export function disableToolboxOnTileView() {
178
+export function hideToolboxOnTileView() {
176
     return (dispatch: Dispatch<any>, getState: Function) => {
179
     return (dispatch: Dispatch<any>, getState: Function) => {
177
-        if (!isLayoutTileView(getState())) {
178
-            return;
179
-        }
180
+        const state = getState();
181
+        const { overflowDrawer } = state['features/toolbox'];
182
+
180
 
183
 
181
-        dispatch(setToolboxEnabled(false));
182
-        dispatch(hideToolbox(true));
184
+        if (!overflowDrawer && isLayoutTileView(state)) {
185
+            dispatch(hideToolbox(true));
186
+        }
183
     };
187
     };
184
 }
188
 }

+ 13
- 12
react/features/toolbox/components/web/Toolbox.js Ver fichero

389
      * @inheritdoc
389
      * @inheritdoc
390
      */
390
      */
391
     componentDidUpdate(prevProps) {
391
     componentDidUpdate(prevProps) {
392
-        // Ensure the dialog is closed when the toolbox becomes hidden.
393
-        if (prevProps._overflowMenuVisible && !this.props._visible) {
394
-            this._onSetOverflowVisible(false);
395
-        }
392
+        const { _dialog, _reactionsEnabled, _participantCount, dispatch, t } = this.props;
393
+
396
 
394
 
397
         if (prevProps._overflowMenuVisible
395
         if (prevProps._overflowMenuVisible
398
             && !prevProps._dialog
396
             && !prevProps._dialog
399
-            && this.props._dialog) {
397
+            && _dialog) {
400
             this._onSetOverflowVisible(false);
398
             this._onSetOverflowVisible(false);
401
-            this.props.dispatch(setToolbarHovered(false));
399
+            dispatch(setToolbarHovered(false));
402
         }
400
         }
403
 
401
 
404
         if (!this.state.reactionsShortcutsRegistered
402
         if (!this.state.reactionsShortcutsRegistered
405
-            && (prevProps._reactionsEnabled !== this.props._reactionsEnabled
406
-            || prevProps._participantCount !== this.props._participantCount)) {
407
-            if (this.props._reactionsEnabled && this.props._participantCount > 1) {
403
+            && (prevProps._reactionsEnabled !== _reactionsEnabled
404
+            || prevProps._participantCount !== _participantCount)) {
405
+            if (_reactionsEnabled && _participantCount > 1) {
408
                 // eslint-disable-next-line react/no-did-update-set-state
406
                 // eslint-disable-next-line react/no-did-update-set-state
409
                 this.setState({
407
                 this.setState({
410
                     reactionsShortcutsRegistered: true
408
                     reactionsShortcutsRegistered: true
411
                 });
409
                 });
412
                 const REACTION_SHORTCUTS = Object.keys(REACTIONS).map(key => {
410
                 const REACTION_SHORTCUTS = Object.keys(REACTIONS).map(key => {
413
                     const onShortcutSendReaction = () => {
411
                     const onShortcutSendReaction = () => {
414
-                        this.props.dispatch(addReactionToBuffer(key));
412
+                        dispatch(addReactionToBuffer(key));
415
                         sendAnalytics(createShortcutEvent(
413
                         sendAnalytics(createShortcutEvent(
416
                             `reaction.${key}`
414
                             `reaction.${key}`
417
                         ));
415
                         ));
420
                     return {
418
                     return {
421
                         character: REACTIONS[key].shortcutChar,
419
                         character: REACTIONS[key].shortcutChar,
422
                         exec: onShortcutSendReaction,
420
                         exec: onShortcutSendReaction,
423
-                        helpDescription: this.props.t(`toolbar.reaction${key.charAt(0).toUpperCase()}${key.slice(1)}`),
421
+                        helpDescription: t(`toolbar.reaction${key.charAt(0).toUpperCase()}${key.slice(1)}`),
424
                         altKey: true
422
                         altKey: true
425
                     };
423
                     };
426
                 });
424
                 });
911
      * @returns {void}
909
      * @returns {void}
912
      */
910
      */
913
     _onMouseOut() {
911
     _onMouseOut() {
914
-        this.props.dispatch(setToolbarHovered(false));
912
+        const { _overflowMenuVisible, dispatch } = this.props;
913
+
914
+        !_overflowMenuVisible && dispatch(setToolbarHovered(false));
915
     }
915
     }
916
 
916
 
917
     _onMouseOver: () => void;
917
     _onMouseOver: () => void;
939
      */
939
      */
940
     _onSetOverflowVisible(visible) {
940
     _onSetOverflowVisible(visible) {
941
         this.props.dispatch(setOverflowMenuVisible(visible));
941
         this.props.dispatch(setOverflowMenuVisible(visible));
942
+        this.props.dispatch(setToolbarHovered(visible));
942
     }
943
     }
943
 
944
 
944
     _onShortcutToggleChat: () => void;
945
     _onShortcutToggleChat: () => void;

+ 15
- 22
react/features/video-menu/components/web/LocalVideoMenuTriggerButton.js Ver fichero

1
 // @flow
1
 // @flow
2
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
+import { batch } from 'react-redux';
4
 
5
 
5
 import { isMobileBrowser } from '../../../base/environment/utils';
6
 import { isMobileBrowser } from '../../../base/environment/utils';
6
 import { translate } from '../../../base/i18n';
7
 import { translate } from '../../../base/i18n';
10
 } from '../../../base/participants';
11
 } from '../../../base/participants';
11
 import { Popover } from '../../../base/popover';
12
 import { Popover } from '../../../base/popover';
12
 import { connect } from '../../../base/redux';
13
 import { connect } from '../../../base/redux';
14
+import { setParticipantContextMenuOpen } from '../../../base/responsive-ui/actions';
13
 import { getLocalVideoTrack } from '../../../base/tracks';
15
 import { getLocalVideoTrack } from '../../../base/tracks';
14
 import ConnectionIndicatorContent from '../../../connection-indicator/components/web/ConnectionIndicatorContent';
16
 import ConnectionIndicatorContent from '../../../connection-indicator/components/web/ConnectionIndicatorContent';
15
-import { setToolboxEnabled, disableToolboxOnTileView } from '../../../toolbox/actions';
16
-import { isToolboxEnabled } from '../../../toolbox/functions';
17
+import { hideToolboxOnTileView } from '../../../toolbox/actions';
17
 import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
18
 import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
18
 import { renderConnectionStatus } from '../../actions.web';
19
 import { renderConnectionStatus } from '../../actions.web';
19
 
20
 
65
      */
66
      */
66
     _showLocalVideoFlipButton: boolean,
67
     _showLocalVideoFlipButton: boolean,
67
 
68
 
68
-    /**
69
-     * Whether the toolbox is enabled or not.
70
-     */
71
-    _toolboxEnabled: boolean,
72
-
73
     /**
69
     /**
74
      * Invoked to obtain translated strings.
70
      * Invoked to obtain translated strings.
75
      */
71
      */
83
  * @extends {Component}
79
  * @extends {Component}
84
  */
80
  */
85
 class LocalVideoMenuTriggerButton extends Component<Props> {
81
 class LocalVideoMenuTriggerButton extends Component<Props> {
86
-    /**
87
-     * Preserve the intial toolbox state.
88
-     */
89
-     initialToolboxEnabled: boolean;
90
-
91
     /**
82
     /**
92
      * Reference to the Popover instance.
83
      * Reference to the Popover instance.
93
      */
84
      */
103
         super(props);
94
         super(props);
104
 
95
 
105
         this.popoverRef = React.createRef();
96
         this.popoverRef = React.createRef();
106
-        this.initialToolboxEnabled = true;
107
         this._onPopoverClose = this._onPopoverClose.bind(this);
97
         this._onPopoverClose = this._onPopoverClose.bind(this);
108
         this._onPopoverOpen = this._onPopoverOpen.bind(this);
98
         this._onPopoverOpen = this._onPopoverOpen.bind(this);
109
     }
99
     }
129
         if (this.props.getRef) {
119
         if (this.props.getRef) {
130
             this.props.getRef(this);
120
             this.props.getRef(this);
131
         }
121
         }
132
-
133
-        this.initialToolboxEnabled = this.props._toolboxEnabled;
134
     }
122
     }
135
 
123
 
136
     /**
124
     /**
181
                     overflowDrawer = { _overflowDrawer }
169
                     overflowDrawer = { _overflowDrawer }
182
                     position = { _menuPosition }
170
                     position = { _menuPosition }
183
                     ref = { this.popoverRef }>
171
                     ref = { this.popoverRef }>
184
-                    {!isMobileBrowser() && (
172
+                    {!_overflowDrawer && (
185
                         <span
173
                         <span
186
                             className = 'popover-trigger local-video-menu-trigger'>
174
                             className = 'popover-trigger local-video-menu-trigger'>
187
-                            <Icon
175
+                            {!isMobileBrowser() && <Icon
188
                                 ariaLabel = { t('dialog.localUserControls') }
176
                                 ariaLabel = { t('dialog.localUserControls') }
189
                                 role = 'button'
177
                                 role = 'button'
190
                                 size = '1em'
178
                                 size = '1em'
191
                                 src = { IconMenuThumb }
179
                                 src = { IconMenuThumb }
192
                                 tabIndex = { 0 }
180
                                 tabIndex = { 0 }
193
                                 title = { t('dialog.localUserControls') } />
181
                                 title = { t('dialog.localUserControls') } />
182
+                            }
194
                         </span>
183
                         </span>
195
                     )}
184
                     )}
196
                 </Popover>
185
                 </Popover>
206
      * @returns {void}
195
      * @returns {void}
207
      */
196
      */
208
     _onPopoverOpen() {
197
     _onPopoverOpen() {
209
-        this.props.dispatch(disableToolboxOnTileView());
198
+        this.props.dispatch(setParticipantContextMenuOpen(true));
199
+        this.props.dispatch(hideToolboxOnTileView());
210
     }
200
     }
211
 
201
 
212
     _onPopoverClose: () => void;
202
     _onPopoverClose: () => void;
217
      * @returns {void}
207
      * @returns {void}
218
      */
208
      */
219
     _onPopoverClose() {
209
     _onPopoverClose() {
220
-        this.props.dispatch(setToolboxEnabled(this.initialToolboxEnabled));
221
-        this.props.dispatch(renderConnectionStatus(false));
210
+        const { dispatch } = this.props;
211
+
212
+        batch(() => {
213
+            dispatch(setParticipantContextMenuOpen(false));
214
+            dispatch(renderConnectionStatus(false));
215
+        });
222
     }
216
     }
223
 }
217
 }
224
 
218
 
258
         _showLocalVideoFlipButton: !disableLocalVideoFlip && videoTrack?.videoType !== 'desktop',
252
         _showLocalVideoFlipButton: !disableLocalVideoFlip && videoTrack?.videoType !== 'desktop',
259
         _overflowDrawer: overflowDrawer,
253
         _overflowDrawer: overflowDrawer,
260
         _localParticipantId: localParticipant.id,
254
         _localParticipantId: localParticipant.id,
261
-        _showConnectionInfo: showConnectionInfo,
262
-        _toolboxEnabled: isToolboxEnabled(state)
255
+        _showConnectionInfo: showConnectionInfo
263
     };
256
     };
264
 }
257
 }
265
 
258
 

+ 18
- 24
react/features/video-menu/components/web/RemoteVideoMenuTriggerButton.js Ver fichero

1
 // @flow
1
 // @flow
2
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
+import { batch } from 'react-redux';
4
 
5
 
5
 import ConnectionIndicatorContent from
6
 import ConnectionIndicatorContent from
6
     '../../../../features/connection-indicator/components/web/ConnectionIndicatorContent';
7
     '../../../../features/connection-indicator/components/web/ConnectionIndicatorContent';
10
 import { getLocalParticipant, getParticipantById, PARTICIPANT_ROLE } from '../../../base/participants';
11
 import { getLocalParticipant, getParticipantById, PARTICIPANT_ROLE } from '../../../base/participants';
11
 import { Popover } from '../../../base/popover';
12
 import { Popover } from '../../../base/popover';
12
 import { connect } from '../../../base/redux';
13
 import { connect } from '../../../base/redux';
14
+import { setParticipantContextMenuOpen } from '../../../base/responsive-ui/actions';
13
 import { requestRemoteControl, stopController } from '../../../remote-control';
15
 import { requestRemoteControl, stopController } from '../../../remote-control';
14
-import { setToolboxEnabled, disableToolboxOnTileView } from '../../../toolbox/actions';
15
-import { isToolboxEnabled } from '../../../toolbox/functions';
16
+import { hideToolboxOnTileView } from '../../../toolbox/actions';
16
 import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
17
 import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
17
 import { renderConnectionStatus } from '../../actions.web';
18
 import { renderConnectionStatus } from '../../actions.web';
18
 
19
 
78
      */
79
      */
79
     _remoteControlState: number,
80
     _remoteControlState: number,
80
 
81
 
81
-    /**
82
-     * Whether the toolbox is enabled or not.
83
-     */
84
-    _toolboxEnabled: boolean,
85
-
86
     /**
82
     /**
87
      * The redux dispatch function.
83
      * The redux dispatch function.
88
      */
84
      */
133
  * @extends {Component}
129
  * @extends {Component}
134
  */
130
  */
135
 class RemoteVideoMenuTriggerButton extends Component<Props> {
131
 class RemoteVideoMenuTriggerButton extends Component<Props> {
136
-    /**
137
-     * Preserve the intial toolbox state.
138
-     */
139
-     initialToolboxEnabled: boolean;
140
-
141
     /**
132
     /**
142
      * Reference to the Popover instance.
133
      * Reference to the Popover instance.
143
      */
134
      */
153
         super(props);
144
         super(props);
154
 
145
 
155
         this.popoverRef = React.createRef();
146
         this.popoverRef = React.createRef();
156
-        this.initialToolboxEnabled = true;
157
         this._onPopoverClose = this._onPopoverClose.bind(this);
147
         this._onPopoverClose = this._onPopoverClose.bind(this);
158
         this._onPopoverOpen = this._onPopoverOpen.bind(this);
148
         this._onPopoverOpen = this._onPopoverOpen.bind(this);
159
     }
149
     }
179
         if (this.props.getRef) {
169
         if (this.props.getRef) {
180
             this.props.getRef(this);
170
             this.props.getRef(this);
181
         }
171
         }
182
-
183
-        this.initialToolboxEnabled = this.props._toolboxEnabled;
184
     }
172
     }
185
 
173
 
186
     /**
174
     /**
202
      * @returns {ReactElement}
190
      * @returns {ReactElement}
203
      */
191
      */
204
     render() {
192
     render() {
205
-        const { _showConnectionInfo, _participantDisplayName, participantID } = this.props;
193
+        const { _overflowDrawer, _showConnectionInfo, _participantDisplayName, participantID } = this.props;
206
         const content = _showConnectionInfo
194
         const content = _showConnectionInfo
207
             ? <ConnectionIndicatorContent participantId = { participantID } />
195
             ? <ConnectionIndicatorContent participantId = { participantID } />
208
             : this._renderRemoteVideoMenu();
196
             : this._renderRemoteVideoMenu();
218
                 content = { content }
206
                 content = { content }
219
                 onPopoverClose = { this._onPopoverClose }
207
                 onPopoverClose = { this._onPopoverClose }
220
                 onPopoverOpen = { this._onPopoverOpen }
208
                 onPopoverOpen = { this._onPopoverOpen }
221
-                overflowDrawer = { this.props._overflowDrawer }
209
+                overflowDrawer = { _overflowDrawer }
222
                 position = { this.props._menuPosition }
210
                 position = { this.props._menuPosition }
223
                 ref = { this.popoverRef }>
211
                 ref = { this.popoverRef }>
224
-                {!isMobileBrowser() && (
212
+                {!_overflowDrawer && (
225
                     <span className = 'popover-trigger remote-video-menu-trigger'>
213
                     <span className = 'popover-trigger remote-video-menu-trigger'>
226
-                        <Icon
214
+                        {!isMobileBrowser() && <Icon
227
                             ariaLabel = { this.props.t('dialog.remoteUserControls', { username }) }
215
                             ariaLabel = { this.props.t('dialog.remoteUserControls', { username }) }
228
                             role = 'button'
216
                             role = 'button'
229
                             size = '1.4em'
217
                             size = '1.4em'
230
                             src = { IconMenuThumb }
218
                             src = { IconMenuThumb }
231
                             tabIndex = { 0 }
219
                             tabIndex = { 0 }
232
                             title = { this.props.t('dialog.remoteUserControls', { username }) } />
220
                             title = { this.props.t('dialog.remoteUserControls', { username }) } />
221
+                        }
233
                     </span>
222
                     </span>
234
                 )}
223
                 )}
235
             </Popover>
224
             </Popover>
244
      * @returns {void}
233
      * @returns {void}
245
      */
234
      */
246
     _onPopoverOpen() {
235
     _onPopoverOpen() {
247
-        this.props.dispatch(disableToolboxOnTileView());
236
+        this.props.dispatch(setParticipantContextMenuOpen(true));
237
+        this.props.dispatch(hideToolboxOnTileView());
248
     }
238
     }
249
 
239
 
250
     _onPopoverClose: () => void;
240
     _onPopoverClose: () => void;
255
      * @returns {void}
245
      * @returns {void}
256
      */
246
      */
257
     _onPopoverClose() {
247
     _onPopoverClose() {
258
-        this.props.dispatch(setToolboxEnabled(this.initialToolboxEnabled));
259
-        this.props.dispatch(renderConnectionStatus(false));
248
+        const { dispatch } = this.props;
249
+
250
+        batch(() => {
251
+            dispatch(setParticipantContextMenuOpen(false));
252
+            dispatch(renderConnectionStatus(false));
253
+        });
260
     }
254
     }
261
 
255
 
262
     /**
256
     /**
349
         if (isMobileBrowser()) {
343
         if (isMobileBrowser()) {
350
             buttons.push(
344
             buttons.push(
351
                 <ConnectionStatusButton
345
                 <ConnectionStatusButton
346
+                    key = 'conn-status'
352
                     participantId = { participantID } />
347
                     participantId = { participantID } />
353
             );
348
             );
354
         }
349
         }
435
         _overflowDrawer: overflowDrawer,
430
         _overflowDrawer: overflowDrawer,
436
         _participantDisplayName,
431
         _participantDisplayName,
437
         _disableGrantModerator: Boolean(disableGrantModerator),
432
         _disableGrantModerator: Boolean(disableGrantModerator),
438
-        _showConnectionInfo: showConnectionInfo,
439
-        _toolboxEnabled: isToolboxEnabled(state)
433
+        _showConnectionInfo: showConnectionInfo
440
     };
434
     };
441
 }
435
 }
442
 
436
 

Loading…
Cancelar
Guardar