Call details screen disable call buttons if call is active

This commit is contained in:
Evan Hahn 2022-02-16 12:33:52 -06:00 committed by GitHub
parent da68def79f
commit fd81d38931
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 60 additions and 22 deletions

View file

@ -3862,7 +3862,7 @@
} }
} }
}, },
"calling__call-notification__button__in-another-call-tooltip": { "calling__in-another-call-tooltip": {
"message": "You are already in a call", "message": "You are already in a call",
"description": "Tooltip in disabled notification button when you're on another call" "description": "Tooltip in disabled notification button when you're on another call"
}, },

View file

@ -137,9 +137,7 @@ function renderCallingNotificationButton(
? i18n('calling__call-back') ? i18n('calling__call-back')
: i18n('calling__call-again'); : i18n('calling__call-again');
if (activeCallConversationId) { if (activeCallConversationId) {
disabledTooltipText = i18n( disabledTooltipText = i18n('calling__in-another-call-tooltip');
'calling__call-notification__button__in-another-call-tooltip'
);
onClick = noop; onClick = noop;
} else { } else {
onClick = () => { onClick = () => {
@ -159,9 +157,7 @@ function renderCallingNotificationButton(
onClick = returnToActiveCall; onClick = returnToActiveCall;
} else { } else {
buttonText = i18n('calling__join'); buttonText = i18n('calling__join');
disabledTooltipText = i18n( disabledTooltipText = i18n('calling__in-another-call-tooltip');
'calling__call-notification__button__in-another-call-tooltip'
);
onClick = noop; onClick = noop;
} }
} else if (deviceCount >= maxDevices) { } else if (deviceCount >= maxDevices) {

View file

@ -1,4 +1,4 @@
// Copyright 2021 Signal Messenger, LLC // Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react'; import * as React from 'react';
@ -46,6 +46,7 @@ const createProps = (hasGroupLink = false, expireTimer?: number): Props => ({
expireTimer, expireTimer,
} }
: conversation, : conversation,
hasActiveCall: false,
hasGroupLink, hasGroupLink,
getPreferredBadge: () => undefined, getPreferredBadge: () => undefined,
i18n, i18n,

View file

@ -1,10 +1,11 @@
// Copyright 2021 Signal Messenger, LLC // Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Button, ButtonIconType, ButtonVariant } from '../../Button'; import { Button, ButtonIconType, ButtonVariant } from '../../Button';
import { Tooltip } from '../../Tooltip';
import type { ConversationType } from '../../../state/ducks/conversations'; import type { ConversationType } from '../../../state/ducks/conversations';
import type { PreferredBadgeSelectorType } from '../../../state/selectors/badges'; import type { PreferredBadgeSelectorType } from '../../../state/selectors/badges';
import { assert } from '../../../util/assert'; import { assert } from '../../../util/assert';
@ -62,6 +63,7 @@ export type StateProps = {
conversation?: ConversationType; conversation?: ConversationType;
hasGroupLink: boolean; hasGroupLink: boolean;
getPreferredBadge: PreferredBadgeSelectorType; getPreferredBadge: PreferredBadgeSelectorType;
hasActiveCall: boolean;
i18n: LocalizerType; i18n: LocalizerType;
isAdmin: boolean; isAdmin: boolean;
isGroup: boolean; isGroup: boolean;
@ -118,6 +120,7 @@ export const ConversationDetails: React.ComponentType<Props> = ({
deleteAvatarFromDisk, deleteAvatarFromDisk,
hasGroupLink, hasGroupLink,
getPreferredBadge, getPreferredBadge,
hasActiveCall,
i18n, i18n,
isAdmin, isAdmin,
isGroup, isGroup,
@ -339,21 +342,19 @@ export const ConversationDetails: React.ComponentType<Props> = ({
<div className="ConversationDetails__header-buttons"> <div className="ConversationDetails__header-buttons">
{!conversation.isMe && ( {!conversation.isMe && (
<> <>
<Button <ConversationDetailsCallButton
icon={ButtonIconType.video} disabled={hasActiveCall}
i18n={i18n}
onClick={onOutgoingVideoCallInConversation} onClick={onOutgoingVideoCallInConversation}
variant={ButtonVariant.Details} type="video"
> />
{i18n('video')}
</Button>
{!isGroup && ( {!isGroup && (
<Button <ConversationDetailsCallButton
icon={ButtonIconType.audio} disabled={hasActiveCall}
i18n={i18n}
onClick={onOutgoingAudioCallInConversation} onClick={onOutgoingAudioCallInConversation}
variant={ButtonVariant.Details} type="audio"
> />
{i18n('audio')}
</Button>
)} )}
</> </>
)} )}
@ -546,3 +547,36 @@ export const ConversationDetails: React.ComponentType<Props> = ({
</div> </div>
); );
}; };
function ConversationDetailsCallButton({
disabled,
i18n,
onClick,
type,
}: Readonly<{
disabled: boolean;
i18n: LocalizerType;
onClick: () => unknown;
type: 'audio' | 'video';
}>) {
const button = (
<Button
disabled={disabled}
icon={ButtonIconType[type]}
onClick={onClick}
variant={ButtonVariant.Details}
>
{i18n(type)}
</Button>
);
if (disabled) {
return (
<Tooltip content={i18n('calling__in-another-call-tooltip')}>
{button}
</Tooltip>
);
}
return button;
}

View file

@ -1176,6 +1176,11 @@ function startCallingLobby({
"startCallingLobby: can't start lobby without a conversation" "startCallingLobby: can't start lobby without a conversation"
); );
strictAssert(
!state.calling.activeCallState,
"startCallingLobby: can't start lobby if a call is active"
);
// The group call device count is considered 0 for a direct call. // The group call device count is considered 0 for a direct call.
const groupCall = getGroupCall(conversationId, state.calling); const groupCall = getGroupCall(conversationId, state.calling);
const groupCallDeviceCount = const groupCallDeviceCount =

View file

@ -1,4 +1,4 @@
// Copyright 2021 Signal Messenger, LLC // Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import { connect } from 'react-redux'; import { connect } from 'react-redux';
@ -13,6 +13,7 @@ import {
getConversationByUuidSelector, getConversationByUuidSelector,
} from '../selectors/conversations'; } from '../selectors/conversations';
import { getGroupMemberships } from '../../util/getGroupMemberships'; import { getGroupMemberships } from '../../util/getGroupMemberships';
import { getActiveCallState } from '../selectors/calling';
import { getAreWeASubscriber } from '../selectors/items'; import { getAreWeASubscriber } from '../selectors/items';
import { getIntl, getTheme } from '../selectors/user'; import { getIntl, getTheme } from '../selectors/user';
import type { MediaItemType } from '../../types/MediaItem'; import type { MediaItemType } from '../../types/MediaItem';
@ -93,6 +94,7 @@ const mapStateToProps = (
...getConversationColorAttributes(conversation), ...getConversationColorAttributes(conversation),
}, },
getPreferredBadge: getPreferredBadgeSelector(state), getPreferredBadge: getPreferredBadgeSelector(state),
hasActiveCall: Boolean(getActiveCallState(state)),
i18n: getIntl(state), i18n: getIntl(state),
isAdmin, isAdmin,
...groupMemberships, ...groupMemberships,