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
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import FocusTrap from 'focus-trap-react';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import {
|
import {
|
||||||
SetLocalAudioType,
|
SetLocalAudioType,
|
||||||
|
@ -204,85 +203,83 @@ export const CallingLobby = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FocusTrap>
|
<div className="module-calling__container">
|
||||||
<div className="module-calling__container">
|
{shouldShowLocalVideo ? (
|
||||||
{shouldShowLocalVideo ? (
|
<video
|
||||||
<video
|
className="module-CallingLobby__local-preview module-CallingLobby__local-preview--camera-is-on"
|
||||||
className="module-CallingLobby__local-preview module-CallingLobby__local-preview--camera-is-on"
|
ref={localVideoRef}
|
||||||
ref={localVideoRef}
|
autoPlay
|
||||||
autoPlay
|
/>
|
||||||
/>
|
) : (
|
||||||
) : (
|
<CallBackgroundBlur
|
||||||
<CallBackgroundBlur
|
className="module-CallingLobby__local-preview module-CallingLobby__local-preview--camera-is-off"
|
||||||
className="module-CallingLobby__local-preview module-CallingLobby__local-preview--camera-is-off"
|
avatarPath={me.avatarPath}
|
||||||
avatarPath={me.avatarPath}
|
color={me.color}
|
||||||
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}
|
i18n={i18n}
|
||||||
isGroupCall={isGroupCall}
|
onClick={toggleVideo}
|
||||||
participantCount={peekedParticipants.length}
|
tooltipDirection={TooltipPlacement.Top}
|
||||||
showParticipantsList={showParticipantsList}
|
|
||||||
toggleParticipants={toggleParticipants}
|
|
||||||
toggleSettings={toggleSettings}
|
|
||||||
onCancel={onCallCanceled}
|
|
||||||
/>
|
/>
|
||||||
|
<CallingButton
|
||||||
<CallingPreCallInfo
|
buttonType={audioButtonType}
|
||||||
conversation={conversation}
|
|
||||||
groupMembers={groupMembers}
|
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
isCallFull={isCallFull}
|
onClick={toggleAudio}
|
||||||
me={me}
|
tooltipDirection={TooltipPlacement.Top}
|
||||||
peekedParticipants={peekedParticipants}
|
|
||||||
ringMode={preCallInfoRingMode}
|
|
||||||
/>
|
/>
|
||||||
|
<CallingButton
|
||||||
<div
|
buttonType={ringButtonType}
|
||||||
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}
|
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
onClick={() => {
|
isVisible={isRingButtonVisible}
|
||||||
setIsCallConnecting(true);
|
onClick={toggleOutgoingRing}
|
||||||
onJoinCall();
|
tooltipDirection={TooltipPlacement.Top}
|
||||||
}}
|
|
||||||
variant={callingLobbyJoinButtonVariant}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</FocusTrap>
|
|
||||||
|
<CallingLobbyJoinButton
|
||||||
|
disabled={!canJoin}
|
||||||
|
i18n={i18n}
|
||||||
|
onClick={() => {
|
||||||
|
setIsCallConnecting(true);
|
||||||
|
onJoinCall();
|
||||||
|
}}
|
||||||
|
variant={callingLobbyJoinButtonVariant}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,12 +3,62 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { noop } from 'lodash';
|
||||||
import { Manager, Reference, Popper } from 'react-popper';
|
import { Manager, Reference, Popper } from 'react-popper';
|
||||||
import type { StrictModifiers } from '@popperjs/core';
|
import type { StrictModifiers } from '@popperjs/core';
|
||||||
import { Theme, themeClassName } from '../util/theme';
|
import { Theme, themeClassName } from '../util/theme';
|
||||||
|
import { refMerger } from '../util/refMerger';
|
||||||
import { offsetDistanceModifier } from '../util/popperUtil';
|
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 {
|
export enum TooltipPlacement {
|
||||||
Top = 'top',
|
Top = 'top',
|
||||||
|
@ -47,12 +97,9 @@ export const Tooltip: React.FC<PropsType> = ({
|
||||||
<Manager>
|
<Manager>
|
||||||
<Reference>
|
<Reference>
|
||||||
{({ ref }) => (
|
{({ ref }) => (
|
||||||
<SmartTooltipEventWrapper
|
<TooltipEventWrapper ref={ref} onHoverChanged={setIsHovering}>
|
||||||
innerRef={ref}
|
|
||||||
onHoverChanged={setIsHovering}
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</SmartTooltipEventWrapper>
|
</TooltipEventWrapper>
|
||||||
)}
|
)}
|
||||||
</Reference>
|
</Reference>
|
||||||
<Popper
|
<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",
|
"rule": "React-useRef",
|
||||||
"path": "ts/components/TooltipEventWrapper.tsx",
|
"path": "ts/components/Tooltip.js",
|
||||||
"line": " const wrapperRef = useRef<HTMLSpanElement | null>(null);",
|
"line": " const wrapperRef = react_1.default.useRef(null);",
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2021-10-21T16:10:14.143Z",
|
"updated": "2020-12-04T00:11:08.128Z",
|
||||||
"reasonDetail": "Used to add (and remove) event listeners."
|
"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",
|
"rule": "React-createRef",
|
||||||
"path": "ts/components/conversation/ConversationHeader.js",
|
"path": "ts/components/conversation/ConversationHeader.js",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue