feat(context-menu) Show participants context menu overlaid in a portal
This commit is contained in:
parent
9ef71e3b15
commit
9f7a4f86d8
|
@ -3,48 +3,45 @@
|
|||
* to allow mouse movement from the popover trigger to the popover itself
|
||||
* without triggering a mouseleave event.
|
||||
*/
|
||||
.popover-mousemove-padding-bottom {
|
||||
bottom: -15px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
%vertical-popover-padding {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 40px;
|
||||
width: 20px;
|
||||
padding: 20px 0;
|
||||
top: -20px;
|
||||
}
|
||||
|
||||
%horizontal-popover-padding {
|
||||
height: 25px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
padding: 0 35px;
|
||||
left: -35px;
|
||||
}
|
||||
|
||||
.popover-mousemove-padding-left {
|
||||
@extend %vertical-popover-padding;
|
||||
left: -20px;
|
||||
left: -35px;
|
||||
}
|
||||
|
||||
.popover-mousemove-padding-right {
|
||||
@extend %vertical-popover-padding;
|
||||
right: -20px;
|
||||
right: -35px;
|
||||
}
|
||||
|
||||
/**
|
||||
* An invisible element is added to the top of the popover to ensure the mouse
|
||||
* stays over the popover when the popover's height is shrunk, which would then
|
||||
* normally leave the mouse outside of the popover itself and cause a mouseleave
|
||||
* event.
|
||||
*/
|
||||
.popover-mouse-padding-top {
|
||||
height: 30px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: -25px;
|
||||
width: 100%;
|
||||
.popover-mousemove-padding-bottom {
|
||||
@extend %horizontal-popover-padding;
|
||||
bottom: -40px;
|
||||
}
|
||||
|
||||
.popover-mousemove-padding-top {
|
||||
@extend %horizontal-popover-padding;
|
||||
top: -40px;
|
||||
}
|
||||
|
||||
.popover {
|
||||
background-color: $popoverBg;
|
||||
border-radius: 3px;
|
||||
margin: -16px -24px;
|
||||
padding: 16px 24px;
|
||||
z-index: $popoverZ;
|
||||
|
|
|
@ -1,35 +1,10 @@
|
|||
/* @flow */
|
||||
|
||||
import InlineDialog from '@atlaskit/inline-dialog';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { Drawer, DrawerPortal } from '../../../toolbox/components/web';
|
||||
|
||||
/**
|
||||
* A map of dialog positions, relative to trigger, to css classes used to
|
||||
* manipulate elements for handling mouse events.
|
||||
*
|
||||
* @private
|
||||
* @type {object}
|
||||
*/
|
||||
const DIALOG_TO_PADDING_POSITION = {
|
||||
'left': 'popover-mousemove-padding-right',
|
||||
'right': 'popover-mousemove-padding-left',
|
||||
'top': 'popover-mousemove-padding-bottom'
|
||||
};
|
||||
|
||||
/**
|
||||
* Takes the position expected by {@code InlineDialog} and maps it to a CSS
|
||||
* class that can be used styling the elements used for preventing mouseleave
|
||||
* events when moving from the trigger to the dialog.
|
||||
*
|
||||
* @param {string} position - From which position the dialog will display.
|
||||
* @private
|
||||
* @returns {string}
|
||||
*/
|
||||
function _mapPositionToPaddingClass(position = 'left') {
|
||||
return DIALOG_TO_PADDING_POSITION[position.split('-')[0]];
|
||||
}
|
||||
import { Drawer, DrawerPortal, DialogPortal } from '../../../toolbox/components/web';
|
||||
import { isMobileBrowser } from '../../environment/utils';
|
||||
import { getContextMenuStyle } from '../functions.web';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link Popover}.
|
||||
|
@ -90,6 +65,11 @@ type Props = {
|
|||
*/
|
||||
type State = {
|
||||
|
||||
/**
|
||||
* The style to apply to the context menu in order to position it correctly.
|
||||
*/
|
||||
contextMenuStyle: Object,
|
||||
|
||||
/**
|
||||
* Whether or not the {@code InlineDialog} should be displayed.
|
||||
*/
|
||||
|
@ -118,6 +98,7 @@ class Popover extends Component<Props, State> {
|
|||
*/
|
||||
_containerRef: Object;
|
||||
|
||||
_contextMenuRef: HTMLElement;
|
||||
|
||||
/**
|
||||
* Initializes a new {@code Popover} instance.
|
||||
|
@ -129,7 +110,8 @@ class Popover extends Component<Props, State> {
|
|||
super(props);
|
||||
|
||||
this.state = {
|
||||
showDialog: false
|
||||
showDialog: false,
|
||||
contextMenuStyle: null
|
||||
};
|
||||
|
||||
// Bind event handlers so they are only bound once for every instance.
|
||||
|
@ -140,6 +122,9 @@ class Popover extends Component<Props, State> {
|
|||
this._onEscKey = this._onEscKey.bind(this);
|
||||
this._onThumbClick = this._onThumbClick.bind(this);
|
||||
this._onTouchStart = this._onTouchStart.bind(this);
|
||||
this._setContextMenuRef = this._setContextMenuRef.bind(this);
|
||||
this._setContextMenuStyle = this._setContextMenuStyle.bind(this);
|
||||
this._getCustomDialogStyle = this._getCustomDialogStyle.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -179,7 +164,7 @@ class Popover extends Component<Props, State> {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { children, className, content, id, overflowDrawer, position } = this.props;
|
||||
const { children, className, content, id, overflowDrawer } = this.props;
|
||||
|
||||
if (overflowDrawer) {
|
||||
return (
|
||||
|
@ -208,16 +193,47 @@ class Popover extends Component<Props, State> {
|
|||
onMouseEnter = { this._onShowDialog }
|
||||
onMouseLeave = { this._onHideDialog }
|
||||
ref = { this._containerRef }>
|
||||
<InlineDialog
|
||||
content = { this._renderContent() }
|
||||
isOpen = { this.state.showDialog }
|
||||
placement = { position }>
|
||||
{ this.state.showDialog && (
|
||||
<DialogPortal
|
||||
getRef = { this._setContextMenuRef }
|
||||
setSize = { this._setContextMenuStyle }
|
||||
style = { this.state.contextMenuStyle }>
|
||||
{this._renderContent()}
|
||||
</DialogPortal>
|
||||
)}
|
||||
{ children }
|
||||
</InlineDialog>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
_setContextMenuStyle: (size: Object) => void;
|
||||
|
||||
/**
|
||||
* Sets the context menu dialog style for positioning it on screen.
|
||||
*
|
||||
* @param {DOMRectReadOnly} size -The size info of the current context menu.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_setContextMenuStyle(size) {
|
||||
const style = this._getCustomDialogStyle(size);
|
||||
|
||||
this.setState({ contextMenuStyle: style });
|
||||
}
|
||||
|
||||
_setContextMenuRef: (elem: HTMLElement) => void;
|
||||
|
||||
/**
|
||||
* Sets the context menu's ref.
|
||||
*
|
||||
* @param {HTMLElement} elem -The html element of the context menu.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_setContextMenuRef(elem) {
|
||||
this._contextMenuRef = elem;
|
||||
}
|
||||
|
||||
_onTouchStart: (event: TouchEvent) => void;
|
||||
|
||||
/**
|
||||
|
@ -230,9 +246,9 @@ class Popover extends Component<Props, State> {
|
|||
_onTouchStart(event) {
|
||||
if (this.state.showDialog
|
||||
&& !this.props.overflowDrawer
|
||||
&& this._containerRef
|
||||
&& this._containerRef.current
|
||||
&& !this._containerRef.current.contains(event.target)) {
|
||||
&& this._contextMenuRef
|
||||
&& this._contextMenuRef.contains
|
||||
&& !this._contextMenuRef.contains(event.target)) {
|
||||
this._onHideDialog();
|
||||
}
|
||||
}
|
||||
|
@ -246,7 +262,10 @@ class Popover extends Component<Props, State> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_onHideDialog() {
|
||||
this.setState({ showDialog: false });
|
||||
this.setState({
|
||||
showDialog: false,
|
||||
contextMenuStyle: null
|
||||
});
|
||||
|
||||
if (this.props.onPopoverClose) {
|
||||
this.props.onPopoverClose();
|
||||
|
@ -327,6 +346,24 @@ class Popover extends Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
_getCustomDialogStyle: (DOMRectReadOnly) => void;
|
||||
|
||||
/**
|
||||
* Gets style for positioning the context menu on screen in regards to the trigger's
|
||||
* position.
|
||||
*
|
||||
* @param {DOMRectReadOnly} size -The current context menu's size info.
|
||||
*
|
||||
* @returns {Object} - The new style of the context menu.
|
||||
*/
|
||||
_getCustomDialogStyle(size) {
|
||||
if (this._containerRef && this._containerRef.current) {
|
||||
const bounds = this._containerRef.current.getBoundingClientRect();
|
||||
|
||||
return getContextMenuStyle(bounds, size, this.props.position);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the React Element to be displayed in the {@code InlineDialog}.
|
||||
* Also adds padding to support moving the mouse from the trigger to the
|
||||
|
@ -336,15 +373,20 @@ class Popover extends Component<Props, State> {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderContent() {
|
||||
const { content, position } = this.props;
|
||||
const { content } = this.props;
|
||||
|
||||
return (
|
||||
<div
|
||||
className = 'popover'
|
||||
className = 'popover popupmenu'
|
||||
onKeyDown = { this._onEscKey }>
|
||||
{ content }
|
||||
<div className = 'popover-mouse-padding-top' />
|
||||
<div className = { _mapPositionToPaddingClass(position) } />
|
||||
{!isMobileBrowser() && (
|
||||
<>
|
||||
<div className = 'popover-mousemove-padding-top' />
|
||||
<div className = 'popover-mousemove-padding-right' />
|
||||
<div className = 'popover-mousemove-padding-left' />
|
||||
<div className = 'popover-mousemove-padding-bottom' />
|
||||
</>)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
// @flow
|
||||
|
||||
const LEFT_RIGHT_OFFSET = 25;
|
||||
const TOP_BOTTOM_OFFSET = 20;
|
||||
|
||||
const getLeftAlignedStyle = bounds => {
|
||||
return {
|
||||
position: 'fixed',
|
||||
right: `${window.innerWidth - bounds.x + LEFT_RIGHT_OFFSET}px`
|
||||
};
|
||||
};
|
||||
|
||||
const getRightAlignedStyle = bounds => {
|
||||
return {
|
||||
position: 'fixed',
|
||||
left: `${bounds.x + bounds.width + LEFT_RIGHT_OFFSET}px`
|
||||
};
|
||||
};
|
||||
|
||||
const getTopAlignedStyle = bounds => {
|
||||
return {
|
||||
position: 'fixed',
|
||||
bottom: `${window.innerHeight - bounds.y + TOP_BOTTOM_OFFSET}px`
|
||||
};
|
||||
};
|
||||
|
||||
const getBottomAlignedStyle = bounds => {
|
||||
return {
|
||||
position: 'fixed',
|
||||
top: `${bounds.y + bounds.height + TOP_BOTTOM_OFFSET}px`
|
||||
};
|
||||
};
|
||||
|
||||
const getLeftRightStartAlign = (bounds, size) => {
|
||||
return {
|
||||
top: `${Math.min(bounds.y + 15, window.innerHeight - size.height - 20)}px`
|
||||
};
|
||||
};
|
||||
|
||||
const getLeftRightMidAlign = (bounds, size) => {
|
||||
return {
|
||||
bottom: `${window.innerHeight - bounds.y - bounds.height - (size.height / 2)}px`
|
||||
};
|
||||
};
|
||||
|
||||
const getLeftRightEndAlign = (bounds, size) => {
|
||||
return {
|
||||
bottom: `${Math.min(window.innerHeight - bounds.y - bounds.height, window.innerHeight - size.height)}px`
|
||||
};
|
||||
};
|
||||
|
||||
const getTopBotStartAlign = bounds => {
|
||||
return {
|
||||
right: `${window.innerWidth - bounds.x + 10}px`
|
||||
};
|
||||
};
|
||||
|
||||
const getTopBotMidAlign = (bounds, size) => {
|
||||
return {
|
||||
right: `${window.innerWidth - bounds.x - (size.width / 2)}px`
|
||||
};
|
||||
};
|
||||
|
||||
const getTopBotEndAlign = bounds => {
|
||||
return {
|
||||
left: `${bounds.x + bounds.width + 10}px`
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the trigger element's and the context menu's bounds/size info and
|
||||
* computes the style to apply to the context menu to positioning it correctly
|
||||
* in regards to the given position info.
|
||||
*
|
||||
* @param {DOMRect} triggerBounds -The bounds info of the trigger html element.
|
||||
* @param {DOMRectReadOnly} dialogSize - The size info of the context menu.
|
||||
* @param {string} position - The position of the context menu in regards to the trigger element.
|
||||
*
|
||||
* @returns {Object} = The style to apply to context menu for positioning it correctly.
|
||||
*/
|
||||
export const getContextMenuStyle = (triggerBounds: DOMRect,
|
||||
dialogSize: DOMRectReadOnly,
|
||||
position: string) => {
|
||||
const parsed = position.split('-');
|
||||
|
||||
switch (parsed[0]) {
|
||||
case 'top': {
|
||||
let alignmentStyle = {};
|
||||
|
||||
if (parsed[1]) {
|
||||
alignmentStyle = parsed[1] === 'start'
|
||||
? getTopBotStartAlign(triggerBounds)
|
||||
: getTopBotEndAlign(triggerBounds);
|
||||
} else {
|
||||
alignmentStyle = getTopBotMidAlign(triggerBounds, dialogSize);
|
||||
}
|
||||
|
||||
return {
|
||||
...getTopAlignedStyle(triggerBounds),
|
||||
...alignmentStyle
|
||||
};
|
||||
}
|
||||
case 'bottom': {
|
||||
let alignmentStyle = {};
|
||||
|
||||
if (parsed[1]) {
|
||||
alignmentStyle = parsed[1] === 'start'
|
||||
? getTopBotStartAlign(triggerBounds)
|
||||
: getTopBotEndAlign(triggerBounds);
|
||||
} else {
|
||||
alignmentStyle = getTopBotMidAlign(triggerBounds, dialogSize);
|
||||
}
|
||||
|
||||
return {
|
||||
...getBottomAlignedStyle(triggerBounds),
|
||||
...alignmentStyle
|
||||
};
|
||||
}
|
||||
case 'left': {
|
||||
let alignmentStyle = {};
|
||||
|
||||
if (parsed[1]) {
|
||||
alignmentStyle = parsed[1] === 'start'
|
||||
? getLeftRightStartAlign(triggerBounds, dialogSize)
|
||||
: getLeftRightEndAlign(triggerBounds, dialogSize);
|
||||
} else {
|
||||
alignmentStyle = getLeftRightMidAlign(triggerBounds, dialogSize);
|
||||
}
|
||||
|
||||
return {
|
||||
...getLeftAlignedStyle(triggerBounds),
|
||||
...alignmentStyle
|
||||
};
|
||||
}
|
||||
case 'right': {
|
||||
let alignmentStyle = {};
|
||||
|
||||
if (parsed[1]) {
|
||||
alignmentStyle = parsed[1] === 'start'
|
||||
? getLeftRightStartAlign(triggerBounds, dialogSize)
|
||||
: getLeftRightEndAlign(triggerBounds, dialogSize);
|
||||
} else {
|
||||
alignmentStyle = getLeftRightMidAlign(triggerBounds, dialogSize);
|
||||
}
|
||||
|
||||
return {
|
||||
...getRightAlignedStyle(triggerBounds),
|
||||
...alignmentStyle
|
||||
};
|
||||
}
|
||||
default: {
|
||||
return {
|
||||
...getLeftAlignedStyle(triggerBounds),
|
||||
...getLeftRightEndAlign(triggerBounds, dialogSize)
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
|
@ -3,7 +3,6 @@
|
|||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { overwriteConfig } from '../base/config';
|
||||
import { isLayoutTileView } from '../video-layout';
|
||||
|
||||
import {
|
||||
CLEAR_TOOLBOX_TIMEOUT,
|
||||
|
@ -134,13 +133,10 @@ export function showToolbox(timeout: number = 0): Object {
|
|||
|
||||
const {
|
||||
enabled,
|
||||
visible,
|
||||
overflowDrawer
|
||||
visible
|
||||
} = state['features/toolbox'];
|
||||
const { contextMenuOpened } = state['features/base/responsive-ui'];
|
||||
const contextMenuOpenedInTileview = isLayoutTileView(state) && contextMenuOpened && !overflowDrawer;
|
||||
|
||||
if (enabled && !visible && !contextMenuOpenedInTileview) {
|
||||
if (enabled && !visible) {
|
||||
dispatch(setToolboxVisible(true));
|
||||
|
||||
// If the Toolbox is always visible, there's no need for a timeout
|
||||
|
@ -178,23 +174,6 @@ export function setOverflowDrawer(displayAsDrawer: boolean) {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Disables and hides the toolbox on demand when in tile view.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
export function hideToolboxOnTileView() {
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
const state = getState();
|
||||
const { overflowDrawer } = state['features/toolbox'];
|
||||
|
||||
if (!overflowDrawer && isLayoutTileView(state)) {
|
||||
dispatch(hideToolbox(true));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals that toolbox timeout should be cleared.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
// @flow
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The component(s) to be displayed within the drawer portal.
|
||||
*/
|
||||
children: React$Node,
|
||||
|
||||
/**
|
||||
* Custom class name to apply on the container div.
|
||||
*/
|
||||
className?: string,
|
||||
|
||||
/**
|
||||
* Function used to get the refferrence to the container div.
|
||||
*/
|
||||
getRef?: Function,
|
||||
|
||||
/**
|
||||
* Function used to get the updated size info of the container on it's resize.
|
||||
*/
|
||||
setSize?: Function,
|
||||
|
||||
/**
|
||||
* Custom style to apply to the container div.
|
||||
*/
|
||||
style?: Object,
|
||||
};
|
||||
|
||||
/**
|
||||
* Component meant to render a drawer at the bottom of the screen,
|
||||
* by creating a portal containing the component's children.
|
||||
*
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
function DialogPortal({ children, className, style, getRef, setSize }: Props) {
|
||||
const [ portalTarget ] = useState(() => {
|
||||
const portalDiv = document.createElement('div');
|
||||
|
||||
return portalDiv;
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (style) {
|
||||
for (const styleProp of Object.keys(style)) {
|
||||
// https://github.com/facebook/flow/issues/3733
|
||||
const objStyle: Object = portalTarget.style;
|
||||
|
||||
objStyle[styleProp] = style[styleProp];
|
||||
}
|
||||
}
|
||||
if (className) {
|
||||
portalTarget.className = className;
|
||||
}
|
||||
}, [ style, className ]);
|
||||
|
||||
useEffect(() => {
|
||||
if (portalTarget && getRef) {
|
||||
getRef(portalTarget);
|
||||
}
|
||||
}, [ portalTarget ]);
|
||||
|
||||
useEffect(() => {
|
||||
const size = {
|
||||
width: 1,
|
||||
height: 1
|
||||
};
|
||||
const observer = new ResizeObserver(entries => {
|
||||
const { contentRect } = entries[0];
|
||||
|
||||
if (contentRect.width !== size.width || contentRect.height !== size.height) {
|
||||
setSize && setSize(contentRect);
|
||||
}
|
||||
});
|
||||
|
||||
if (document.body) {
|
||||
document.body.appendChild(portalTarget);
|
||||
observer.observe(portalTarget);
|
||||
}
|
||||
|
||||
return () => {
|
||||
observer.unobserve(portalTarget);
|
||||
if (document.body) {
|
||||
document.body.removeChild(portalTarget);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return ReactDOM.createPortal(
|
||||
children,
|
||||
portalTarget
|
||||
);
|
||||
}
|
||||
|
||||
export default DialogPortal;
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import DialogPortal from './DialogPortal';
|
||||
|
||||
type Props = {
|
||||
|
||||
|
@ -18,29 +18,10 @@ type Props = {
|
|||
* @returns {ReactElement}
|
||||
*/
|
||||
function DrawerPortal({ children }: Props) {
|
||||
const [ portalTarget ] = useState(() => {
|
||||
const portalDiv = document.createElement('div');
|
||||
|
||||
portalDiv.className = 'drawer-portal';
|
||||
|
||||
return portalDiv;
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (document.body) {
|
||||
document.body.appendChild(portalTarget);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (document.body) {
|
||||
document.body.removeChild(portalTarget);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return ReactDOM.createPortal(
|
||||
children,
|
||||
portalTarget
|
||||
return (
|
||||
<DialogPortal className = 'drawer-portal'>
|
||||
{ children }
|
||||
</DialogPortal>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,3 +4,4 @@ export { default as ToolbarButton } from './ToolbarButton';
|
|||
export { default as Toolbox } from './Toolbox';
|
||||
export { default as Drawer } from './Drawer';
|
||||
export { default as DrawerPortal } from './DrawerPortal';
|
||||
export { default as DialogPortal } from './DialogPortal';
|
||||
|
|
|
@ -14,7 +14,6 @@ import { connect } from '../../../base/redux';
|
|||
import { setParticipantContextMenuOpen } from '../../../base/responsive-ui/actions';
|
||||
import { getLocalVideoTrack } from '../../../base/tracks';
|
||||
import ConnectionIndicatorContent from '../../../connection-indicator/components/web/ConnectionIndicatorContent';
|
||||
import { hideToolboxOnTileView } from '../../../toolbox/actions';
|
||||
import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
|
||||
import { renderConnectionStatus } from '../../actions.web';
|
||||
|
||||
|
@ -196,7 +195,6 @@ class LocalVideoMenuTriggerButton extends Component<Props> {
|
|||
*/
|
||||
_onPopoverOpen() {
|
||||
this.props.dispatch(setParticipantContextMenuOpen(true));
|
||||
this.props.dispatch(hideToolboxOnTileView());
|
||||
}
|
||||
|
||||
_onPopoverClose: () => void;
|
||||
|
|
|
@ -13,7 +13,6 @@ import { Popover } from '../../../base/popover';
|
|||
import { connect } from '../../../base/redux';
|
||||
import { setParticipantContextMenuOpen } from '../../../base/responsive-ui/actions';
|
||||
import { requestRemoteControl, stopController } from '../../../remote-control';
|
||||
import { hideToolboxOnTileView } from '../../../toolbox/actions';
|
||||
import { getCurrentLayout, LAYOUTS } from '../../../video-layout';
|
||||
import { renderConnectionStatus } from '../../actions.web';
|
||||
|
||||
|
@ -234,7 +233,6 @@ class RemoteVideoMenuTriggerButton extends Component<Props> {
|
|||
*/
|
||||
_onPopoverOpen() {
|
||||
this.props.dispatch(setParticipantContextMenuOpen(true));
|
||||
this.props.dispatch(hideToolboxOnTileView());
|
||||
}
|
||||
|
||||
_onPopoverClose: () => void;
|
||||
|
|
Loading…
Reference in New Issue