Revert "Use focus trap for CallingLobby"
This reverts commit b38b22f49d
.
This commit is contained in:
parent
b38b22f49d
commit
56031336a9
5 changed files with 132 additions and 179 deletions
|
@ -2,7 +2,6 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import FocusTrap from 'focus-trap-react';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
SetLocalAudioType,
|
||||
|
@ -204,85 +203,83 @@ export const CallingLobby = ({
|
|||
}
|
||||
|
||||
return (
|
||||
<FocusTrap>
|
||||
<div className="module-calling__container">
|
||||
{shouldShowLocalVideo ? (
|
||||
<video
|
||||
className="module-CallingLobby__local-preview module-CallingLobby__local-preview--camera-is-on"
|
||||
ref={localVideoRef}
|
||||
autoPlay
|
||||
/>
|
||||
) : (
|
||||
<CallBackgroundBlur
|
||||
className="module-CallingLobby__local-preview module-CallingLobby__local-preview--camera-is-off"
|
||||
avatarPath={me.avatarPath}
|
||||
color={me.color}
|
||||
/>
|
||||
<div className="module-calling__container">
|
||||
{shouldShowLocalVideo ? (
|
||||
<video
|
||||
className="module-CallingLobby__local-preview module-CallingLobby__local-preview--camera-is-on"
|
||||
ref={localVideoRef}
|
||||
autoPlay
|
||||
/>
|
||||
) : (
|
||||
<CallBackgroundBlur
|
||||
className="module-CallingLobby__local-preview module-CallingLobby__local-preview--camera-is-off"
|
||||
avatarPath={me.avatarPath}
|
||||
color={me.color}
|
||||
/>
|
||||
)}
|
||||
|
||||
<CallingHeader
|
||||
i18n={i18n}
|
||||
isGroupCall={isGroupCall}
|
||||
participantCount={peekedParticipants.length}
|
||||
showParticipantsList={showParticipantsList}
|
||||
toggleParticipants={toggleParticipants}
|
||||
toggleSettings={toggleSettings}
|
||||
onCancel={onCallCanceled}
|
||||
/>
|
||||
|
||||
<CallingPreCallInfo
|
||||
conversation={conversation}
|
||||
groupMembers={groupMembers}
|
||||
i18n={i18n}
|
||||
isCallFull={isCallFull}
|
||||
me={me}
|
||||
peekedParticipants={peekedParticipants}
|
||||
ringMode={preCallInfoRingMode}
|
||||
/>
|
||||
|
||||
<div
|
||||
className={classNames(
|
||||
'module-CallingLobby__camera-is-off',
|
||||
`module-CallingLobby__camera-is-off--${
|
||||
shouldShowLocalVideo ? 'invisible' : 'visible'
|
||||
}`
|
||||
)}
|
||||
>
|
||||
{i18n('calling__your-video-is-off')}
|
||||
</div>
|
||||
|
||||
<CallingHeader
|
||||
<div className="module-calling__buttons module-calling__buttons--inline">
|
||||
<CallingButton
|
||||
buttonType={videoButtonType}
|
||||
i18n={i18n}
|
||||
isGroupCall={isGroupCall}
|
||||
participantCount={peekedParticipants.length}
|
||||
showParticipantsList={showParticipantsList}
|
||||
toggleParticipants={toggleParticipants}
|
||||
toggleSettings={toggleSettings}
|
||||
onCancel={onCallCanceled}
|
||||
onClick={toggleVideo}
|
||||
tooltipDirection={TooltipPlacement.Top}
|
||||
/>
|
||||
|
||||
<CallingPreCallInfo
|
||||
conversation={conversation}
|
||||
groupMembers={groupMembers}
|
||||
<CallingButton
|
||||
buttonType={audioButtonType}
|
||||
i18n={i18n}
|
||||
isCallFull={isCallFull}
|
||||
me={me}
|
||||
peekedParticipants={peekedParticipants}
|
||||
ringMode={preCallInfoRingMode}
|
||||
onClick={toggleAudio}
|
||||
tooltipDirection={TooltipPlacement.Top}
|
||||
/>
|
||||
|
||||
<div
|
||||
className={classNames(
|
||||
'module-CallingLobby__camera-is-off',
|
||||
`module-CallingLobby__camera-is-off--${
|
||||
shouldShowLocalVideo ? 'invisible' : 'visible'
|
||||
}`
|
||||
)}
|
||||
>
|
||||
{i18n('calling__your-video-is-off')}
|
||||
</div>
|
||||
|
||||
<div className="module-calling__buttons module-calling__buttons--inline">
|
||||
<CallingButton
|
||||
buttonType={videoButtonType}
|
||||
i18n={i18n}
|
||||
onClick={toggleVideo}
|
||||
tooltipDirection={TooltipPlacement.Top}
|
||||
/>
|
||||
<CallingButton
|
||||
buttonType={audioButtonType}
|
||||
i18n={i18n}
|
||||
onClick={toggleAudio}
|
||||
tooltipDirection={TooltipPlacement.Top}
|
||||
/>
|
||||
<CallingButton
|
||||
buttonType={ringButtonType}
|
||||
i18n={i18n}
|
||||
isVisible={isRingButtonVisible}
|
||||
onClick={toggleOutgoingRing}
|
||||
tooltipDirection={TooltipPlacement.Top}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<CallingLobbyJoinButton
|
||||
disabled={!canJoin}
|
||||
<CallingButton
|
||||
buttonType={ringButtonType}
|
||||
i18n={i18n}
|
||||
onClick={() => {
|
||||
setIsCallConnecting(true);
|
||||
onJoinCall();
|
||||
}}
|
||||
variant={callingLobbyJoinButtonVariant}
|
||||
isVisible={isRingButtonVisible}
|
||||
onClick={toggleOutgoingRing}
|
||||
tooltipDirection={TooltipPlacement.Top}
|
||||
/>
|
||||
</div>
|
||||
</FocusTrap>
|
||||
|
||||
<CallingLobbyJoinButton
|
||||
disabled={!canJoin}
|
||||
i18n={i18n}
|
||||
onClick={() => {
|
||||
setIsCallConnecting(true);
|
||||
onJoinCall();
|
||||
}}
|
||||
variant={callingLobbyJoinButtonVariant}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -3,12 +3,62 @@
|
|||
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { noop } from 'lodash';
|
||||
import { Manager, Reference, Popper } from 'react-popper';
|
||||
import type { StrictModifiers } from '@popperjs/core';
|
||||
import { Theme, themeClassName } from '../util/theme';
|
||||
import { refMerger } from '../util/refMerger';
|
||||
import { offsetDistanceModifier } from '../util/popperUtil';
|
||||
|
||||
import { SmartTooltipEventWrapper } from '../state/smart/TooltipEventWrapper';
|
||||
type EventWrapperPropsType = {
|
||||
children: React.ReactNode;
|
||||
onHoverChanged: (_: boolean) => void;
|
||||
};
|
||||
|
||||
// React doesn't reliably fire `onMouseLeave` or `onMouseOut` events if wrapping a
|
||||
// disabled button. This uses native browser events to avoid that.
|
||||
//
|
||||
// See <https://lecstor.com/react-disabled-button-onmouseleave/>.
|
||||
const TooltipEventWrapper = React.forwardRef<
|
||||
HTMLSpanElement,
|
||||
EventWrapperPropsType
|
||||
>(({ onHoverChanged, children }, ref) => {
|
||||
const wrapperRef = React.useRef<HTMLSpanElement | null>(null);
|
||||
|
||||
const on = React.useCallback(() => {
|
||||
onHoverChanged(true);
|
||||
}, [onHoverChanged]);
|
||||
|
||||
const off = React.useCallback(() => {
|
||||
onHoverChanged(false);
|
||||
}, [onHoverChanged]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const wrapperEl = wrapperRef.current;
|
||||
|
||||
if (!wrapperEl) {
|
||||
return noop;
|
||||
}
|
||||
|
||||
wrapperEl.addEventListener('mouseenter', on);
|
||||
wrapperEl.addEventListener('mouseleave', off);
|
||||
|
||||
return () => {
|
||||
wrapperEl.removeEventListener('mouseenter', on);
|
||||
wrapperEl.removeEventListener('mouseleave', off);
|
||||
};
|
||||
}, [on, off]);
|
||||
|
||||
return (
|
||||
<span
|
||||
onFocus={on}
|
||||
onBlur={off}
|
||||
ref={refMerger<HTMLSpanElement>(ref, wrapperRef)}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
});
|
||||
|
||||
export enum TooltipPlacement {
|
||||
Top = 'top',
|
||||
|
@ -47,12 +97,9 @@ export const Tooltip: React.FC<PropsType> = ({
|
|||
<Manager>
|
||||
<Reference>
|
||||
{({ ref }) => (
|
||||
<SmartTooltipEventWrapper
|
||||
innerRef={ref}
|
||||
onHoverChanged={setIsHovering}
|
||||
>
|
||||
<TooltipEventWrapper ref={ref} onHoverChanged={setIsHovering}>
|
||||
{children}
|
||||
</SmartTooltipEventWrapper>
|
||||
</TooltipEventWrapper>
|
||||
)}
|
||||
</Reference>
|
||||
<Popper
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
// Copyright 2020-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { Ref, useCallback, useEffect, useRef } from 'react';
|
||||
import { noop } from 'lodash';
|
||||
|
||||
import { refMerger } from '../util/refMerger';
|
||||
import type { InteractionModeType } from '../state/ducks/conversations';
|
||||
|
||||
type PropsType = {
|
||||
children: React.ReactNode;
|
||||
interactionMode: InteractionModeType;
|
||||
// Matches Popper's RefHandler type
|
||||
innerRef: Ref<HTMLElement>;
|
||||
onHoverChanged: (_: boolean) => void;
|
||||
};
|
||||
|
||||
// React doesn't reliably fire `onMouseLeave` or `onMouseOut` events if wrapping a
|
||||
// disabled button. This uses native browser events to avoid that.
|
||||
//
|
||||
// See <https://lecstor.com/react-disabled-button-onmouseleave/>.
|
||||
export const TooltipEventWrapper: React.FC<PropsType> = ({
|
||||
onHoverChanged,
|
||||
children,
|
||||
interactionMode,
|
||||
innerRef,
|
||||
}) => {
|
||||
const wrapperRef = useRef<HTMLSpanElement | null>(null);
|
||||
|
||||
const on = useCallback(() => {
|
||||
onHoverChanged(true);
|
||||
}, [onHoverChanged]);
|
||||
|
||||
const off = useCallback(() => {
|
||||
onHoverChanged(false);
|
||||
}, [onHoverChanged]);
|
||||
|
||||
const onFocus = useCallback(() => {
|
||||
if (interactionMode === 'keyboard') {
|
||||
on();
|
||||
}
|
||||
}, [on, interactionMode]);
|
||||
|
||||
useEffect(() => {
|
||||
const wrapperEl = wrapperRef.current;
|
||||
|
||||
if (!wrapperEl) {
|
||||
return noop;
|
||||
}
|
||||
|
||||
wrapperEl.addEventListener('mouseenter', on);
|
||||
wrapperEl.addEventListener('mouseleave', off);
|
||||
|
||||
return () => {
|
||||
wrapperEl.removeEventListener('mouseenter', on);
|
||||
wrapperEl.removeEventListener('mouseleave', off);
|
||||
};
|
||||
}, [on, off]);
|
||||
|
||||
return (
|
||||
<span
|
||||
onFocus={onFocus}
|
||||
onBlur={off}
|
||||
ref={refMerger<HTMLSpanElement>(innerRef, wrapperRef)}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
};
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { Ref } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { mapDispatchToProps } from '../actions';
|
||||
import { StateType } from '../reducer';
|
||||
|
||||
import { TooltipEventWrapper } from '../../components/TooltipEventWrapper';
|
||||
import { getInteractionMode } from '../selectors/user';
|
||||
|
||||
type ExternalProps = {
|
||||
// Matches Popper's RefHandler type
|
||||
innerRef: Ref<HTMLElement>;
|
||||
children: React.ReactNode;
|
||||
onHoverChanged: (_: boolean) => void;
|
||||
};
|
||||
|
||||
const mapStateToProps = (state: StateType, props: ExternalProps) => {
|
||||
return {
|
||||
...props,
|
||||
interactionMode: getInteractionMode(state),
|
||||
};
|
||||
};
|
||||
|
||||
const smart = connect(mapStateToProps, mapDispatchToProps);
|
||||
|
||||
export const SmartTooltipEventWrapper = smart(TooltipEventWrapper);
|
|
@ -12763,12 +12763,19 @@
|
|||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/TooltipEventWrapper.tsx",
|
||||
"line": " const wrapperRef = useRef<HTMLSpanElement | null>(null);",
|
||||
"path": "ts/components/Tooltip.js",
|
||||
"line": " const wrapperRef = react_1.default.useRef(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-10-21T16:10:14.143Z",
|
||||
"updated": "2020-12-04T00:11:08.128Z",
|
||||
"reasonDetail": "Used to add (and remove) event listeners."
|
||||
},
|
||||
{
|
||||
"rule": "React-useRef",
|
||||
"path": "ts/components/Tooltip.tsx",
|
||||
"line": " const wrapperRef = React.useRef<HTMLSpanElement | null>(null);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-07-30T16:57:33.618Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/ConversationHeader.js",
|
||||
|
|
Loading…
Add table
Reference in a new issue