Call lobby join button text for call links requiring approval

This commit is contained in:
ayumi-signal 2024-04-29 14:31:44 -07:00 committed by GitHub
parent a0b4126b52
commit c531c64410
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 80 additions and 10 deletions

View file

@ -1625,6 +1625,10 @@
"messageformat": "Call full",
"description": "Button in the call lobby when you can't join because the call is full"
},
"icu:CallingLobbyJoinButton--ask-to-join": {
"messageformat": "Ask to join",
"description": "Button label in the call lobby for joining a call link which requires admin approval"
},
"icu:calling__button--video-disabled": {
"messageformat": "Camera disabled",
"description": "Button tooltip label when the camera is disabled"

View file

@ -53,6 +53,7 @@ import { CallingAdhocCallInfo } from './CallingAdhocCallInfo';
import { callLinkRootKeyToUrl } from '../util/callLinkRootKeyToUrl';
import { ToastType } from '../types/Toast';
import type { ShowToastAction } from '../state/ducks/toast';
import { isSharingPhoneNumberWithEverybody } from '../util/phoneNumberSharingMode';
const GROUP_CALL_RING_DURATION = 60 * 1000;
@ -257,6 +258,7 @@ function ActiveCallManager({
| undefined
| Array<Pick<ConversationType, 'id' | 'firstName' | 'title'>>;
let isConvoTooBigToRing = false;
let isAdhocAdminApprovalRequired = false;
let isAdhocJoinRequestPending = false;
switch (activeCall.callMode) {
@ -286,8 +288,11 @@ function ActiveCallManager({
isCallFull = activeCall.deviceCount >= activeCall.maxDevices;
isConvoTooBigToRing = activeCall.isConversationTooBigToRing;
({ groupMembers } = activeCall);
isAdhocAdminApprovalRequired =
!callLink?.adminKey &&
callLink?.restrictions === CallLinkRestrictions.AdminApproval;
isAdhocJoinRequestPending =
callLink?.restrictions === CallLinkRestrictions.AdminApproval &&
isAdhocAdminApprovalRequired &&
activeCall.joinState === GroupCallJoinState.Pending;
break;
}
@ -324,9 +329,11 @@ function ActiveCallManager({
hasLocalAudio={hasLocalAudio}
hasLocalVideo={hasLocalVideo}
i18n={i18n}
isAdhocAdminApprovalRequired={isAdhocAdminApprovalRequired}
isAdhocJoinRequestPending={isAdhocJoinRequestPending}
isCallFull={isCallFull}
isConversationTooBigToRing={isConvoTooBigToRing}
isSharingPhoneNumberWithEverybody={isSharingPhoneNumberWithEverybody()}
me={me}
onCallCanceled={cancelActiveCall}
onJoinCall={joinActiveCall}

View file

@ -20,6 +20,7 @@ import {
} from '../test-both/helpers/getDefaultConversation';
import { CallingToastProvider } from './CallingToast';
import { CallMode } from '../types/Calling';
import { getDefaultCallLinkConversation } from '../test-both/helpers/fakeCallLink';
const i18n = setupI18n('en', enMessages);
@ -33,15 +34,24 @@ const camera = {
},
};
const getConversation = (callMode: CallMode) => {
if (callMode === CallMode.Group) {
return getDefaultConversation({
title: 'Tahoe Trip',
type: 'group',
});
}
if (callMode === CallMode.Adhoc) {
return getDefaultCallLinkConversation();
}
return getDefaultConversation();
};
const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => {
const callMode = overrideProps.callMode ?? CallMode.Direct;
const conversation =
callMode === CallMode.Group
? getDefaultConversation({
title: 'Tahoe Trip',
type: 'group',
})
: getDefaultConversation();
const conversation = getConversation(callMode);
return {
availableCameras: overrideProps.availableCameras || [camera],
@ -55,9 +65,13 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => {
hasLocalAudio: overrideProps.hasLocalAudio ?? true,
hasLocalVideo: overrideProps.hasLocalVideo ?? false,
i18n,
isAdhocAdminApprovalRequired:
overrideProps.isAdhocAdminApprovalRequired ?? false,
isAdhocJoinRequestPending: false,
isConversationTooBigToRing: false,
isCallFull: overrideProps.isCallFull ?? false,
isSharingPhoneNumberWithEverybody:
overrideProps.isSharingPhoneNumberWithEverybody ?? false,
me:
overrideProps.me ||
getDefaultConversation({
@ -206,3 +220,20 @@ export function GroupCallWith0PeekedParticipantsBigGroup(): JSX.Element {
});
return <CallingLobby {...props} />;
}
export function CallLink(): JSX.Element {
const props = createProps({
callMode: CallMode.Adhoc,
});
return <CallingLobby {...props} />;
}
// Due to storybook font loading, if you directly load this story then
// the button width is not calculated correctly
export function CallLinkAdminApproval(): JSX.Element {
const props = createProps({
callMode: CallMode.Adhoc,
isAdhocAdminApprovalRequired: true,
});
return <CallingLobby {...props} />;
}

View file

@ -28,7 +28,6 @@ import type { ConversationType } from '../state/ducks/conversations';
import { useCallingToasts } from './CallingToast';
import { CallingButtonToastsContainer } from './CallingToastManager';
import { isGroupOrAdhocCallMode } from '../util/isGroupOrAdhocCall';
import { isSharingPhoneNumberWithEverybody } from '../util/phoneNumberSharingMode';
export type PropsType = {
availableCameras: Array<MediaDeviceInfo>;
@ -59,9 +58,11 @@ export type PropsType = {
hasLocalAudio: boolean;
hasLocalVideo: boolean;
i18n: LocalizerType;
isAdhocAdminApprovalRequired: boolean;
isAdhocJoinRequestPending: boolean;
isConversationTooBigToRing: boolean;
isCallFull?: boolean;
isSharingPhoneNumberWithEverybody: boolean;
me: Readonly<
Pick<ConversationType, 'avatarPath' | 'color' | 'id' | 'serviceId'>
>;
@ -87,9 +88,11 @@ export function CallingLobby({
hasLocalAudio,
hasLocalVideo,
i18n,
isAdhocAdminApprovalRequired,
isAdhocJoinRequestPending,
isCallFull = false,
isConversationTooBigToRing,
isSharingPhoneNumberWithEverybody,
me,
onCallCanceled,
onJoinCall,
@ -214,6 +217,8 @@ export function CallingLobby({
callingLobbyJoinButtonVariant = CallingLobbyJoinButtonVariant.CallIsFull;
} else if (isCallConnecting) {
callingLobbyJoinButtonVariant = CallingLobbyJoinButtonVariant.Loading;
} else if (isAdhocAdminApprovalRequired) {
callingLobbyJoinButtonVariant = CallingLobbyJoinButtonVariant.AskToJoin;
} else if (peekedParticipants.length || callMode === CallMode.Adhoc) {
callingLobbyJoinButtonVariant = CallingLobbyJoinButtonVariant.Join;
} else {
@ -303,7 +308,7 @@ export function CallingLobby({
{callMode === CallMode.Adhoc && (
<div className="CallingLobby__CallLinkNotice">
{isSharingPhoneNumberWithEverybody()
{isSharingPhoneNumberWithEverybody
? i18n('icu:CallingLobby__CallLinkNotice--phone-sharing')
: i18n('icu:CallingLobby__CallLinkNotice')}
</div>

View file

@ -14,6 +14,7 @@ export enum CallingLobbyJoinButtonVariant {
Join = 'Join',
Loading = 'Loading',
Start = 'Start',
AskToJoin = 'AskToJoin',
}
type PropsType = {
@ -55,6 +56,9 @@ export function CallingLobbyJoinButton({
[CallingLobbyJoinButtonVariant.Start]: i18n(
'icu:CallingLobbyJoinButton--start'
),
[CallingLobbyJoinButtonVariant.AskToJoin]: i18n(
'icu:CallingLobbyJoinButton--ask-to-join'
),
};
return (

View file

@ -1,5 +1,6 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { CallingConversationType } from '../../types/Calling';
import type { CallLinkType } from '../../types/CallLink';
import { CallLinkRestrictions } from '../../types/CallLink';
import { MONTH } from '../../util/durations/constants';
@ -24,3 +25,21 @@ export const FAKE_CALL_LINK_WITH_ADMIN_KEY: CallLinkType = {
roomId: 'c097eb04cc278d6bc7ed9fb2ddeac00dc9646ae6ddb38513dad9a8a4fe3c38f4',
rootKey: 'bpmc-mrgn-hntf-mffd-mndd-xbxk-zmgq-qszg',
};
export function getDefaultCallLinkConversation(
callLinkOverrideProps: Partial<CallLinkType> = {}
): CallingConversationType {
const { roomId: id, name: title } = {
...FAKE_CALL_LINK,
...callLinkOverrideProps,
};
return {
id,
type: 'callLink',
isMe: false,
title,
sharedGroupNames: [],
acceptedMessageRequest: true,
badges: [],
};
}