Show leave button and spinner while requesting to join call link

This commit is contained in:
ayumi-signal 2024-05-02 13:57:17 -07:00 committed by GitHub
parent c18559b6da
commit bd5134a7ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 132 additions and 11 deletions

View file

@ -1613,6 +1613,10 @@
"messageformat": "Anyone who joins this call via the link will see your name, photo, and phone number.",
"description": "Toast shown in call lobby before joining a call link call to inform user that profile info will be shared, when the phone number sharing account setting is enabled."
},
"icu:CallingLobby__CallLinkNotice--join-request-pending": {
"messageformat": "Waiting to be let in…",
"description": "Notice shown in call lobby after you requested to join a call link to indicate your request is pending approval."
},
"icu:CallingLobbyJoinButton--join": {
"messageformat": "Join",
"description": "Button label in the call lobby for joining a call"

View file

@ -46,9 +46,19 @@
background: $color-black-alpha-60;
color: $color-white;
border-radius: 10px;
align-items: center;
text-align: center;
}
.CallingLobby__CallLinkNotice--join-request-pending {
@include font-body-1;
width: auto;
}
.CallingLobby__CallLinkJoinRequestPendingSpinner {
margin-inline-end: 8px;
}
.CallingLobby__Footer {
display: flex;
width: 100%;

View file

@ -0,0 +1,33 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
.SpinnerV2 {
animation: SpinnerV2-rotate 2s linear infinite;
}
.SpinnerV2__Path {
stroke: $color-gray-15;
stroke-linecap: round;
animation: SpinnerV2-dash 1.5s ease-in-out infinite;
}
@keyframes SpinnerV2-rotate {
100% {
transform: rotate(360deg);
}
}
@keyframes SpinnerV2-dash {
0% {
stroke-dasharray: 2%, 300%;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 180%, 300%;
stroke-dashoffset: -70%;
}
100% {
stroke-dasharray: 180%, 300%;
stroke-dashoffset: -248%;
}
}

View file

@ -147,6 +147,7 @@
@import './components/ShortcutGuide.scss';
@import './components/SignalConnectionsModal.scss';
@import './components/Slider.scss';
@import './components/SpinnerV2.scss';
@import './components/StagedLinkPreview.scss';
@import './components/StickerManager.scss';
@import './components/Stories.scss';

View file

@ -67,7 +67,7 @@ const createProps = (overrideProps: Partial<PropsType> = {}): PropsType => {
i18n,
isAdhocAdminApprovalRequired:
overrideProps.isAdhocAdminApprovalRequired ?? false,
isAdhocJoinRequestPending: false,
isAdhocJoinRequestPending: overrideProps.isAdhocJoinRequestPending ?? false,
isConversationTooBigToRing: false,
isCallFull: overrideProps.isCallFull ?? false,
isSharingPhoneNumberWithEverybody:
@ -237,3 +237,12 @@ export function CallLinkAdminApproval(): JSX.Element {
});
return <CallingLobby {...props} />;
}
export function CallLinkJoinRequestPending(): JSX.Element {
const props = createProps({
callMode: CallMode.Adhoc,
isAdhocAdminApprovalRequired: true,
isAdhocJoinRequestPending: true,
});
return <CallingLobby {...props} />;
}

View file

@ -28,6 +28,8 @@ import type { ConversationType } from '../state/ducks/conversations';
import { useCallingToasts } from './CallingToast';
import { CallingButtonToastsContainer } from './CallingToastManager';
import { isGroupOrAdhocCallMode } from '../util/isGroupOrAdhocCall';
import { Button, ButtonVariant } from './Button';
import { SpinnerV2 } from './SpinnerV2';
export type PropsType = {
availableCameras: Array<MediaDeviceInfo>;
@ -211,6 +213,9 @@ export function CallingLobby({
}
const canJoin = !isCallFull && !isCallConnecting && isOnline;
const canLeave =
(isAdhocAdminApprovalRequired && isCallConnecting) ||
isAdhocJoinRequestPending;
let callingLobbyJoinButtonVariant: CallingLobbyJoinButtonVariant;
if (isCallFull) {
@ -306,7 +311,16 @@ export function CallingLobby({
{i18n('icu:calling__your-video-is-off')}
</div>
{callMode === CallMode.Adhoc && (
{callMode === CallMode.Adhoc && isAdhocJoinRequestPending ? (
<div className="CallingLobby__CallLinkNotice CallingLobby__CallLinkNotice--join-request-pending">
<SpinnerV2
className="CallingLobby__CallLinkJoinRequestPendingSpinner"
size={16}
strokeWidth={3}
/>
{i18n('icu:CallingLobby__CallLinkNotice--join-request-pending')}
</div>
) : (
<div className="CallingLobby__CallLinkNotice">
{isSharingPhoneNumberWithEverybody
? i18n('icu:CallingLobby__CallLinkNotice--phone-sharing')
@ -350,15 +364,25 @@ export function CallingLobby({
/>
</div>
<div className="CallControls__JoinLeaveButtonContainer">
<CallingLobbyJoinButton
disabled={!canJoin}
i18n={i18n}
onClick={() => {
setIsCallConnecting(true);
onJoinCall();
}}
variant={callingLobbyJoinButtonVariant}
/>
{canLeave ? (
<Button
className="CallControls__JoinLeaveButton CallControls__JoinLeaveButton--hangup"
onClick={onCallCanceled}
variant={ButtonVariant.Destructive}
>
{i18n('icu:CallControls__JoinLeaveButton--hangup-group')}
</Button>
) : (
<CallingLobbyJoinButton
disabled={!canJoin}
i18n={i18n}
onClick={() => {
setIsCallConnecting(true);
onJoinCall();
}}
variant={callingLobbyJoinButtonVariant}
/>
)}
</div>
</div>
<div className="module-calling__spacer CallControls__OuterSpacer" />

View file

@ -0,0 +1,40 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import classNames from 'classnames';
export const SpinnerSvgSizes = ['small', 'normal'] as const;
export type SpinnerSvgSize = typeof SpinnerSvgSizes[number];
export type Props = {
className?: string;
size: number;
strokeWidth: number;
};
export function SpinnerV2({
className,
size,
strokeWidth,
}: Props): JSX.Element {
return (
<svg
className={classNames('SpinnerV2', className)}
viewBox={`0 0 ${size * 2} ${size * 2}`}
style={{
height: size,
width: size,
}}
>
<circle
className="SpinnerV2__Path"
cx={size}
cy={size}
r={size * 0.8}
fill="none"
strokeWidth={strokeWidth}
/>
</svg>
);
}