fix(Thumbnail, Drawer): Remove hover state; Prevent outside propagation

This commit is contained in:
Mihai-Andrei Uscat 2021-07-20 11:30:12 +03:00 committed by Mihai-Andrei Uscat
parent c657f360e1
commit b7ab3ea052
3 changed files with 74 additions and 41 deletions

View File

@ -4,16 +4,28 @@
right: 0; right: 0;
bottom: 0; bottom: 0;
z-index: $drawerZ; z-index: $drawerZ;
background-color: #141414;
border-radius: 16px 16px 0 0; border-radius: 16px 16px 0 0;
} }
.drawer-portal::after {
content: '';
background-color: $participantsPaneBgColor;
margin-bottom: env(safe-area-inset-bottom, 0);
}
.drawer-menu-container {
height: 100vh;
display: flex;
align-items: flex-end;
}
.drawer-menu { .drawer-menu {
max-height: calc(80vh - 64px); max-height: calc(80vh - 64px);
background: #242528; background: #242528;
border-radius: 16px 16px 0 0; border-radius: 16px 16px 0 0;
overflow-y: hidden; overflow-y: hidden;
margin-bottom: env(safe-area-inset-bottom, 0); margin-bottom: env(safe-area-inset-bottom, 0);
width: 100%;
.drawer-toggle { .drawer-toggle {
display: flex; display: flex;

View File

@ -2,10 +2,10 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { isMobileBrowser } from '../../../../../react/features/base/environment/utils';
import { createScreenSharingIssueEvent, sendAnalytics } from '../../../analytics'; import { createScreenSharingIssueEvent, sendAnalytics } from '../../../analytics';
import { AudioLevelIndicator } from '../../../audio-level-indicator'; import { AudioLevelIndicator } from '../../../audio-level-indicator';
import { Avatar } from '../../../base/avatar'; import { Avatar } from '../../../base/avatar';
import { isMobileBrowser } from '../../../base/environment/utils';
import JitsiMeetJS from '../../../base/lib-jitsi-meet/_'; import JitsiMeetJS from '../../../base/lib-jitsi-meet/_';
import { MEDIA_TYPE, VideoTrack } from '../../../base/media'; import { MEDIA_TYPE, VideoTrack } from '../../../base/media';
import { import {
@ -139,6 +139,11 @@ export type Props = {|
*/ */
_isCurrentlyOnLargeVideo: boolean, _isCurrentlyOnLargeVideo: boolean,
/**
* Whether we are currently running in a mobile browser.
*/
_isMobile: boolean,
/** /**
* Indicates whether the participant is screen sharing. * Indicates whether the participant is screen sharing.
*/ */
@ -612,7 +617,7 @@ class Thumbnail extends Component<Props, State> {
* @returns {ReactElement} * @returns {ReactElement}
*/ */
_renderFakeParticipant() { _renderFakeParticipant() {
const { _participant: { avatarURL } } = this.props; const { _isMobile, _participant: { avatarURL } } = this.props;
const styles = this._getStyles(); const styles = this._getStyles();
const containerClassName = this._getContainerClassName(); const containerClassName = this._getContainerClassName();
@ -621,8 +626,10 @@ class Thumbnail extends Component<Props, State> {
className = { containerClassName } className = { containerClassName }
id = 'sharedVideoContainer' id = 'sharedVideoContainer'
onClick = { this._onClick } onClick = { this._onClick }
onMouseEnter = { this._onMouseEnter } { ...(_isMobile ? {} : {
onMouseLeave = { this._onMouseLeave } onMouseEnter: this._onMouseEnter,
onMouseLeave: this._onMouseLeave
}) }
style = { styles.thumbnail }> style = { styles.thumbnail }>
{avatarURL ? ( {avatarURL ? (
<img <img
@ -753,6 +760,7 @@ class Thumbnail extends Component<Props, State> {
const { const {
_defaultLocalDisplayName, _defaultLocalDisplayName,
_disableLocalVideoFlip, _disableLocalVideoFlip,
_isMobile,
_isScreenSharing, _isScreenSharing,
_localFlipX, _localFlipX,
_disableProfile, _disableProfile,
@ -772,13 +780,17 @@ class Thumbnail extends Component<Props, State> {
className = { containerClassName } className = { containerClassName }
id = 'localVideoContainer' id = 'localVideoContainer'
onClick = { this._onClick } onClick = { this._onClick }
onMouseEnter = { this._onMouseEnter } { ...(_isMobile
onMouseLeave = { this._onMouseLeave } ? {
{ ...(isMobileBrowser() ? { onTouchEnd: this._onTouchEnd,
onTouchEnd: this._onTouchEnd, onTouchMove: this._onTouchMove,
onTouchMove: this._onTouchMove, onTouchStart: this._onTouchStart
onTouchStart: this._onTouchStart }
} : {}) } : {
onMouseEnter: this._onMouseEnter,
onMouseLeave: this._onMouseLeave
}
) }
style = { styles.thumbnail }> style = { styles.thumbnail }>
<div className = 'videocontainer__background' /> <div className = 'videocontainer__background' />
<span id = 'localVideoWrapper'> <span id = 'localVideoWrapper'>
@ -875,6 +887,7 @@ class Thumbnail extends Component<Props, State> {
*/ */
_renderRemoteParticipant() { _renderRemoteParticipant() {
const { const {
_isMobile,
_isTestModeEnabled, _isTestModeEnabled,
_participant, _participant,
_startSilent, _startSilent,
@ -909,13 +922,17 @@ class Thumbnail extends Component<Props, State> {
className = { containerClassName } className = { containerClassName }
id = { `participant_${id}` } id = { `participant_${id}` }
onClick = { this._onClick } onClick = { this._onClick }
onMouseEnter = { this._onMouseEnter } { ...(_isMobile
onMouseLeave = { this._onMouseLeave } ? {
{ ...(isMobileBrowser() ? { onTouchEnd: this._onTouchEnd,
onTouchEnd: this._onTouchEnd, onTouchMove: this._onTouchMove,
onTouchMove: this._onTouchMove, onTouchStart: this._onTouchStart
onTouchStart: this._onTouchStart }
} : {}) } : {
onMouseEnter: this._onMouseEnter,
onMouseLeave: this._onMouseLeave
}
) }
style = { styles.thumbnail }> style = { styles.thumbnail }>
{ {
_videoTrack && <VideoTrack _videoTrack && <VideoTrack
@ -1031,6 +1048,7 @@ function _mapStateToProps(state, ownProps): Object {
} = state['features/base/config']; } = state['features/base/config'];
const { NORMAL = 8 } = interfaceConfig.INDICATOR_FONT_SIZES || {}; const { NORMAL = 8 } = interfaceConfig.INDICATOR_FONT_SIZES || {};
const { localFlipX } = state['features/base/settings']; const { localFlipX } = state['features/base/settings'];
const _isMobile = isMobileBrowser();
switch (_currentLayout) { switch (_currentLayout) {
@ -1072,7 +1090,7 @@ function _mapStateToProps(state, ownProps): Object {
return { return {
_audioTrack, _audioTrack,
_connectionIndicatorAutoHideEnabled: interfaceConfig.CONNECTION_INDICATOR_AUTO_HIDE_ENABLED, _connectionIndicatorAutoHideEnabled: interfaceConfig.CONNECTION_INDICATOR_AUTO_HIDE_ENABLED,
_connectionIndicatorDisabled: isMobileBrowser() || interfaceConfig.CONNECTION_INDICATOR_DISABLED, _connectionIndicatorDisabled: _isMobile || interfaceConfig.CONNECTION_INDICATOR_DISABLED,
_currentLayout, _currentLayout,
_defaultLocalDisplayName: interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME, _defaultLocalDisplayName: interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME,
_disableLocalVideoFlip: Boolean(disableLocalVideoFlip), _disableLocalVideoFlip: Boolean(disableLocalVideoFlip),
@ -1081,6 +1099,7 @@ function _mapStateToProps(state, ownProps): Object {
_isAudioOnly: Boolean(state['features/base/audio-only'].enabled), _isAudioOnly: Boolean(state['features/base/audio-only'].enabled),
_isCurrentlyOnLargeVideo: state['features/large-video']?.participantId === id, _isCurrentlyOnLargeVideo: state['features/large-video']?.participantId === id,
_isDominantSpeakerDisabled: interfaceConfig.DISABLE_DOMINANT_SPEAKER_INDICATOR, _isDominantSpeakerDisabled: interfaceConfig.DISABLE_DOMINANT_SPEAKER_INDICATOR,
_isMobile,
_isScreenSharing: _videoTrack?.videoType === 'desktop', _isScreenSharing: _videoTrack?.videoType === 'desktop',
_isTestModeEnabled: isTestModeEnabled(state), _isTestModeEnabled: isTestModeEnabled(state),
_isVideoPlayable: id && isVideoPlayable(state, id), _isVideoPlayable: id && isVideoPlayable(state, id),

View File

@ -1,6 +1,6 @@
// @flow // @flow
import React, { useEffect, useRef } from 'react'; import React, { useCallback } from 'react';
type Props = { type Props = {
@ -30,36 +30,38 @@ function Drawer({
children, children,
isOpen, isOpen,
onClose }: Props) { onClose }: Props) {
const drawerRef: Object = useRef(null);
/** /**
* Closes the drawer when clicking or touching outside of it. * Handles clicks within the menu, preventing the propagation of the click event.
* *
* @param {Event} event - Mouse down/start touch event object. * @param {Object} event - The click event.
* @returns {void} * @returns {void}
*/ */
function handleOutsideClickOrTouch(event: Event) { const handleInsideClick = useCallback(event => {
if (drawerRef.current && !drawerRef.current.contains(event.target)) { event.stopPropagation();
onClose(); }, []);
}
}
useEffect(() => { /**
window.addEventListener('mousedown', handleOutsideClickOrTouch); * Handles clicks outside of the menu, closing it, and also stopping further propagation.
window.addEventListener('touchstart', handleOutsideClickOrTouch); *
* @param {Object} event - The click event.
return () => { * @returns {void}
window.removeEventListener('mousedown', handleOutsideClickOrTouch); */
window.removeEventListener('touchstart', handleOutsideClickOrTouch); const handleOutsideClick = useCallback(event => {
}; event.stopPropagation();
}, [ drawerRef ]); onClose();
}, [ onClose ]);
return ( return (
isOpen ? ( isOpen ? (
<div <div
className = 'drawer-menu' className = 'drawer-menu-container'
ref = { drawerRef }> onClick = { handleOutsideClick }>
{children} <div
className = 'drawer-menu'
onClick = { handleInsideClick }>
{children}
</div>
</div> </div>
) : null ) : null
); );