Group calls: mute in the lobby if joining a large call

This commit is contained in:
Evan Hahn 2022-01-07 12:01:23 -06:00 committed by GitHub
parent 09af7eeece
commit f8bbf5c998
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 499 additions and 279 deletions

View file

@ -1,4 +1,4 @@
// Copyright 2020-2021 Signal Messenger, LLC
// Copyright 2020-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -51,11 +51,11 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => {
(isGroupCall ? times(3, () => getDefaultConversation()) : undefined),
hasLocalAudio: boolean(
'hasLocalAudio',
overrideProps.hasLocalAudio || false
overrideProps.hasLocalAudio ?? true
),
hasLocalVideo: boolean(
'hasLocalVideo',
overrideProps.hasLocalVideo || false
overrideProps.hasLocalVideo ?? false
),
i18n,
isGroupCall,
@ -122,9 +122,9 @@ story.add('Local Video', () => {
return <CallingLobby {...props} />;
});
story.add('Local Video', () => {
story.add('Initially muted', () => {
const props = createProps({
hasLocalVideo: true,
hasLocalAudio: false,
});
return <CallingLobby {...props} />;
});

View file

@ -1,4 +1,4 @@
// Copyright 2020-2021 Signal Messenger, LLC
// Copyright 2020-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
@ -13,6 +13,7 @@ import { CallingButton, CallingButtonType } from './CallingButton';
import { TooltipPlacement } from './Tooltip';
import { CallBackgroundBlur } from './CallBackgroundBlur';
import { CallingHeader } from './CallingHeader';
import { CallingToast, DEFAULT_LIFETIME } from './CallingToast';
import { CallingPreCallInfo, RingMode } from './CallingPreCallInfo';
import {
CallingLobbyJoinButton,
@ -92,6 +93,21 @@ export const CallingLobby = ({
toggleSettings,
outgoingRing,
}: PropsType): JSX.Element => {
const [isMutedToastVisible, setIsMutedToastVisible] = React.useState(
!hasLocalAudio
);
React.useEffect(() => {
if (!isMutedToastVisible) {
return;
}
const timeout = setTimeout(() => {
setIsMutedToastVisible(false);
}, DEFAULT_LIFETIME);
return () => {
clearTimeout(timeout);
};
}, [isMutedToastVisible]);
const localVideoRef = React.useRef<null | HTMLVideoElement>(null);
const shouldShowLocalVideo = hasLocalVideo && availableCameras.length > 0;
@ -221,6 +237,15 @@ export const CallingLobby = ({
/>
)}
<CallingToast
isVisible={isMutedToastVisible}
onClick={() => setIsMutedToastVisible(false)}
>
{i18n(
'calling__lobby-automatically-muted-because-there-are-a-lot-of-people'
)}
</CallingToast>
<CallingHeader
i18n={i18n}
isGroupCall={isGroupCall}

View file

@ -0,0 +1,27 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { FunctionComponent } from 'react';
import React from 'react';
import classNames from 'classnames';
type PropsType = {
isVisible: boolean;
onClick: () => unknown;
};
export const DEFAULT_LIFETIME = 5000;
export const CallingToast: FunctionComponent<PropsType> = ({
isVisible,
onClick,
children,
}) => (
<button
className={classNames('CallingToast', !isVisible && 'CallingToast--hidden')}
type="button"
onClick={onClick}
>
{children}
</button>
);

View file

@ -1,12 +1,12 @@
// Copyright 2020-2021 Signal Messenger, LLC
// Copyright 2020-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { useCallback, useEffect, useRef, useState } from 'react';
import classNames from 'classnames';
import type { ActiveCallType } from '../types/Calling';
import { CallMode, GroupCallConnectionState } from '../types/Calling';
import type { ConversationType } from '../state/ducks/conversations';
import type { LocalizerType } from '../types/Util';
import { CallingToast, DEFAULT_LIFETIME } from './CallingToast';
type PropsType = {
activeCall: ActiveCallType;
@ -101,8 +101,6 @@ function useScreenSharingToast({ activeCall, i18n }: PropsType): ToastType {
return result;
}
const DEFAULT_DELAY = 5000;
// In the future, this component should show toasts when users join or leave. See
// DESKTOP-902.
export const CallingToastManager: React.FC<PropsType> = props => {
@ -131,7 +129,7 @@ export const CallingToastManager: React.FC<PropsType> = props => {
if (timeoutRef && timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
timeoutRef.current = setTimeout(dismissToast, DEFAULT_DELAY);
timeoutRef.current = setTimeout(dismissToast, DEFAULT_LIFETIME);
}
setToastMessage(toast.message);
@ -144,17 +142,9 @@ export const CallingToastManager: React.FC<PropsType> = props => {
};
}, [dismissToast, setToastMessage, timeoutRef, toast]);
const isVisible = Boolean(toastMessage);
return (
<button
className={classNames('module-ongoing-call__toast', {
'module-ongoing-call__toast--hidden': !isVisible,
})}
type="button"
onClick={dismissToast}
>
<CallingToast isVisible={Boolean(toastMessage)} onClick={dismissToast}>
{toastMessage}
</button>
</CallingToast>
);
};