CallScreen interactivity fixes
This commit is contained in:
parent
427055ea47
commit
4dcbb7352f
4 changed files with 64 additions and 37 deletions
|
@ -75,6 +75,41 @@ export type PropsType = {
|
|||
toggleSpeakerView: () => void;
|
||||
};
|
||||
|
||||
type DirectCallHeaderMessagePropsType = {
|
||||
i18n: LocalizerType;
|
||||
callState: CallState;
|
||||
joinedAt?: number;
|
||||
};
|
||||
|
||||
function DirectCallHeaderMessage({
|
||||
callState,
|
||||
i18n,
|
||||
joinedAt,
|
||||
}: DirectCallHeaderMessagePropsType): JSX.Element | null {
|
||||
const [acceptedDuration, setAcceptedDuration] = useState<
|
||||
number | undefined
|
||||
>();
|
||||
|
||||
useEffect(() => {
|
||||
if (!joinedAt) {
|
||||
return noop;
|
||||
}
|
||||
// It's really jumpy with a value of 500ms.
|
||||
const interval = setInterval(() => {
|
||||
setAcceptedDuration(Date.now() - joinedAt);
|
||||
}, 100);
|
||||
return clearInterval.bind(null, interval);
|
||||
}, [joinedAt]);
|
||||
|
||||
if (callState === CallState.Reconnecting) {
|
||||
return <>{i18n('callReconnecting')}</>;
|
||||
}
|
||||
if (callState === CallState.Accepted && acceptedDuration) {
|
||||
return <>{i18n('callDuration', [renderDuration(acceptedDuration)])}</>;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export const CallScreen: React.FC<PropsType> = ({
|
||||
activeCall,
|
||||
getGroupCallVideoFrameSource,
|
||||
|
@ -145,7 +180,6 @@ export const CallScreen: React.FC<PropsType> = ({
|
|||
setControlsHover(false);
|
||||
}, [setControlsHover]);
|
||||
|
||||
const [acceptedDuration, setAcceptedDuration] = useState<number | null>(null);
|
||||
const [showControls, setShowControls] = useState(true);
|
||||
|
||||
const localVideoRef = useRef<HTMLVideoElement | null>(null);
|
||||
|
@ -157,17 +191,6 @@ export const CallScreen: React.FC<PropsType> = ({
|
|||
};
|
||||
}, [setLocalPreview, setRendererCanvas]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!joinedAt) {
|
||||
return noop;
|
||||
}
|
||||
// It's really jumpy with a value of 500ms.
|
||||
const interval = setInterval(() => {
|
||||
setAcceptedDuration(Date.now() - joinedAt);
|
||||
}, 100);
|
||||
return clearInterval.bind(null, interval);
|
||||
}, [joinedAt]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!showControls || stickyControls || controlsHover) {
|
||||
return noop;
|
||||
|
@ -175,7 +198,7 @@ export const CallScreen: React.FC<PropsType> = ({
|
|||
const timer = setTimeout(() => {
|
||||
setShowControls(false);
|
||||
}, 5000);
|
||||
return clearInterval.bind(null, timer);
|
||||
return clearTimeout.bind(null, timer);
|
||||
}, [showControls, stickyControls, controlsHover]);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -215,7 +238,7 @@ export const CallScreen: React.FC<PropsType> = ({
|
|||
|
||||
let isRinging: boolean;
|
||||
let hasCallStarted: boolean;
|
||||
let headerMessage: string | undefined;
|
||||
let headerMessage: ReactNode | undefined;
|
||||
let headerTitle: string | undefined;
|
||||
let isConnected: boolean;
|
||||
let participantCount: number;
|
||||
|
@ -227,10 +250,12 @@ export const CallScreen: React.FC<PropsType> = ({
|
|||
activeCall.callState === CallState.Prering ||
|
||||
activeCall.callState === CallState.Ringing;
|
||||
hasCallStarted = !isRinging;
|
||||
headerMessage = renderDirectCallHeaderMessage(
|
||||
i18n,
|
||||
activeCall.callState || CallState.Prering,
|
||||
acceptedDuration
|
||||
headerMessage = (
|
||||
<DirectCallHeaderMessage
|
||||
i18n={i18n}
|
||||
callState={activeCall.callState || CallState.Prering}
|
||||
joinedAt={joinedAt}
|
||||
/>
|
||||
);
|
||||
headerTitle = isRinging ? undefined : conversation.title;
|
||||
isConnected = activeCall.callState === CallState.Accepted;
|
||||
|
@ -252,7 +277,6 @@ export const CallScreen: React.FC<PropsType> = ({
|
|||
activeCall.outgoingRing && !activeCall.remoteParticipants.length;
|
||||
hasCallStarted = activeCall.joinState !== GroupCallJoinState.NotJoined;
|
||||
participantCount = activeCall.remoteParticipants.length + 1;
|
||||
headerMessage = undefined;
|
||||
|
||||
if (isRinging) {
|
||||
headerTitle = undefined;
|
||||
|
@ -399,6 +423,9 @@ export const CallScreen: React.FC<PropsType> = ({
|
|||
hasCallStarted ? 'call-started' : 'call-not-started'
|
||||
}`
|
||||
)}
|
||||
onFocus={() => {
|
||||
setShowControls(true);
|
||||
}}
|
||||
onMouseMove={() => {
|
||||
setShowControls(true);
|
||||
}}
|
||||
|
@ -451,27 +478,33 @@ export const CallScreen: React.FC<PropsType> = ({
|
|||
'module-ongoing-call__footer__actions',
|
||||
controlsFadeClass
|
||||
)}
|
||||
onMouseEnter={onControlsMouseEnter}
|
||||
onMouseLeave={onControlsMouseLeave}
|
||||
>
|
||||
<CallingButton
|
||||
buttonType={presentingButtonType}
|
||||
i18n={i18n}
|
||||
onMouseEnter={onControlsMouseEnter}
|
||||
onMouseLeave={onControlsMouseLeave}
|
||||
onClick={togglePresenting}
|
||||
/>
|
||||
<CallingButton
|
||||
buttonType={videoButtonType}
|
||||
i18n={i18n}
|
||||
onMouseEnter={onControlsMouseEnter}
|
||||
onMouseLeave={onControlsMouseLeave}
|
||||
onClick={toggleVideo}
|
||||
/>
|
||||
<CallingButton
|
||||
buttonType={audioButtonType}
|
||||
i18n={i18n}
|
||||
onMouseEnter={onControlsMouseEnter}
|
||||
onMouseLeave={onControlsMouseLeave}
|
||||
onClick={toggleAudio}
|
||||
/>
|
||||
<CallingButton
|
||||
buttonType={CallingButtonType.HANG_UP}
|
||||
i18n={i18n}
|
||||
onMouseEnter={onControlsMouseEnter}
|
||||
onMouseLeave={onControlsMouseLeave}
|
||||
onClick={() => {
|
||||
hangUp({ conversationId: conversation.id });
|
||||
}}
|
||||
|
@ -502,20 +535,6 @@ function getCallModeClassSuffix(
|
|||
}
|
||||
}
|
||||
|
||||
function renderDirectCallHeaderMessage(
|
||||
i18n: LocalizerType,
|
||||
callState: CallState,
|
||||
acceptedDuration: null | number
|
||||
): string | undefined {
|
||||
if (callState === CallState.Reconnecting) {
|
||||
return i18n('callReconnecting');
|
||||
}
|
||||
if (callState === CallState.Accepted && acceptedDuration) {
|
||||
return i18n('callDuration', [renderDuration(acceptedDuration)]);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function renderDuration(ms: number): string {
|
||||
const secs = Math.floor((ms / 1000) % 60)
|
||||
.toString()
|
||||
|
|
|
@ -19,6 +19,8 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
|
|||
select('buttonType', CallingButtonType, CallingButtonType.HANG_UP),
|
||||
i18n,
|
||||
onClick: action('on-click'),
|
||||
onMouseEnter: action('on-mouse-enter'),
|
||||
onMouseLeave: action('on-mouse-leave'),
|
||||
tooltipDirection: select(
|
||||
'tooltipDirection',
|
||||
TooltipPlacement,
|
||||
|
|
|
@ -29,6 +29,8 @@ export type PropsType = {
|
|||
i18n: LocalizerType;
|
||||
isVisible?: boolean;
|
||||
onClick: () => void;
|
||||
onMouseEnter?: () => void;
|
||||
onMouseLeave?: () => void;
|
||||
tooltipDirection?: TooltipPlacement;
|
||||
};
|
||||
|
||||
|
@ -37,6 +39,8 @@ export const CallingButton = ({
|
|||
i18n,
|
||||
isVisible = true,
|
||||
onClick,
|
||||
onMouseEnter,
|
||||
onMouseLeave,
|
||||
tooltipDirection,
|
||||
}: PropsType): JSX.Element => {
|
||||
const uniqueButtonId = useMemo(() => uuid(), []);
|
||||
|
@ -128,6 +132,8 @@ export const CallingButton = ({
|
|||
disabled={disabled}
|
||||
id={uniqueButtonId}
|
||||
onClick={onClick}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
type="button"
|
||||
>
|
||||
<div />
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2020-2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import React, { ReactNode } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { Tooltip } from './Tooltip';
|
||||
|
@ -11,7 +11,7 @@ export type PropsType = {
|
|||
i18n: LocalizerType;
|
||||
isInSpeakerView?: boolean;
|
||||
isGroupCall?: boolean;
|
||||
message?: string;
|
||||
message?: ReactNode;
|
||||
onCancel?: () => void;
|
||||
participantCount: number;
|
||||
showParticipantsList: boolean;
|
||||
|
|
Loading…
Add table
Reference in a new issue