diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 5cd91e36e1..a33ea82efb 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -3862,7 +3862,7 @@ } } }, - "calling__call-notification__button__in-another-call-tooltip": { + "calling__in-another-call-tooltip": { "message": "You are already in a call", "description": "Tooltip in disabled notification button when you're on another call" }, diff --git a/ts/components/conversation/CallingNotification.tsx b/ts/components/conversation/CallingNotification.tsx index 53cef45a2a..f22585bfda 100644 --- a/ts/components/conversation/CallingNotification.tsx +++ b/ts/components/conversation/CallingNotification.tsx @@ -137,9 +137,7 @@ function renderCallingNotificationButton( ? i18n('calling__call-back') : i18n('calling__call-again'); if (activeCallConversationId) { - disabledTooltipText = i18n( - 'calling__call-notification__button__in-another-call-tooltip' - ); + disabledTooltipText = i18n('calling__in-another-call-tooltip'); onClick = noop; } else { onClick = () => { @@ -159,9 +157,7 @@ function renderCallingNotificationButton( onClick = returnToActiveCall; } else { buttonText = i18n('calling__join'); - disabledTooltipText = i18n( - 'calling__call-notification__button__in-another-call-tooltip' - ); + disabledTooltipText = i18n('calling__in-another-call-tooltip'); onClick = noop; } } else if (deviceCount >= maxDevices) { diff --git a/ts/components/conversation/conversation-details/ConversationDetails.stories.tsx b/ts/components/conversation/conversation-details/ConversationDetails.stories.tsx index dafde3f38e..c63bbf140f 100644 --- a/ts/components/conversation/conversation-details/ConversationDetails.stories.tsx +++ b/ts/components/conversation/conversation-details/ConversationDetails.stories.tsx @@ -1,4 +1,4 @@ -// Copyright 2021 Signal Messenger, LLC +// Copyright 2021-2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; @@ -46,6 +46,7 @@ const createProps = (hasGroupLink = false, expireTimer?: number): Props => ({ expireTimer, } : conversation, + hasActiveCall: false, hasGroupLink, getPreferredBadge: () => undefined, i18n, diff --git a/ts/components/conversation/conversation-details/ConversationDetails.tsx b/ts/components/conversation/conversation-details/ConversationDetails.tsx index dc551e4efa..464aab3c3a 100644 --- a/ts/components/conversation/conversation-details/ConversationDetails.tsx +++ b/ts/components/conversation/conversation-details/ConversationDetails.tsx @@ -1,10 +1,11 @@ -// Copyright 2021 Signal Messenger, LLC +// Copyright 2021-2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import type { ReactNode } from 'react'; import React, { useState } from 'react'; import { Button, ButtonIconType, ButtonVariant } from '../../Button'; +import { Tooltip } from '../../Tooltip'; import type { ConversationType } from '../../../state/ducks/conversations'; import type { PreferredBadgeSelectorType } from '../../../state/selectors/badges'; import { assert } from '../../../util/assert'; @@ -62,6 +63,7 @@ export type StateProps = { conversation?: ConversationType; hasGroupLink: boolean; getPreferredBadge: PreferredBadgeSelectorType; + hasActiveCall: boolean; i18n: LocalizerType; isAdmin: boolean; isGroup: boolean; @@ -118,6 +120,7 @@ export const ConversationDetails: React.ComponentType = ({ deleteAvatarFromDisk, hasGroupLink, getPreferredBadge, + hasActiveCall, i18n, isAdmin, isGroup, @@ -339,21 +342,19 @@ export const ConversationDetails: React.ComponentType = ({
{!conversation.isMe && ( <> - + type="video" + /> {!isGroup && ( - + type="audio" + /> )} )} @@ -546,3 +547,36 @@ export const ConversationDetails: React.ComponentType = ({
); }; + +function ConversationDetailsCallButton({ + disabled, + i18n, + onClick, + type, +}: Readonly<{ + disabled: boolean; + i18n: LocalizerType; + onClick: () => unknown; + type: 'audio' | 'video'; +}>) { + const button = ( + + ); + + if (disabled) { + return ( + + {button} + + ); + } + + return button; +} diff --git a/ts/state/ducks/calling.ts b/ts/state/ducks/calling.ts index c775ba0677..3d065132e4 100644 --- a/ts/state/ducks/calling.ts +++ b/ts/state/ducks/calling.ts @@ -1176,6 +1176,11 @@ function startCallingLobby({ "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. const groupCall = getGroupCall(conversationId, state.calling); const groupCallDeviceCount = diff --git a/ts/state/smart/ConversationDetails.tsx b/ts/state/smart/ConversationDetails.tsx index 34e08c8529..3150160d19 100644 --- a/ts/state/smart/ConversationDetails.tsx +++ b/ts/state/smart/ConversationDetails.tsx @@ -1,4 +1,4 @@ -// Copyright 2021 Signal Messenger, LLC +// Copyright 2021-2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import { connect } from 'react-redux'; @@ -13,6 +13,7 @@ import { getConversationByUuidSelector, } from '../selectors/conversations'; import { getGroupMemberships } from '../../util/getGroupMemberships'; +import { getActiveCallState } from '../selectors/calling'; import { getAreWeASubscriber } from '../selectors/items'; import { getIntl, getTheme } from '../selectors/user'; import type { MediaItemType } from '../../types/MediaItem'; @@ -93,6 +94,7 @@ const mapStateToProps = ( ...getConversationColorAttributes(conversation), }, getPreferredBadge: getPreferredBadgeSelector(state), + hasActiveCall: Boolean(getActiveCallState(state)), i18n: getIntl(state), isAdmin, ...groupMemberships,