Show leave button and spinner while requesting to join call link
This commit is contained in:
parent
c18559b6da
commit
bd5134a7ce
7 changed files with 132 additions and 11 deletions
|
@ -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"
|
||||
|
|
|
@ -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%;
|
||||
|
|
33
stylesheets/components/SpinnerV2.scss
Normal file
33
stylesheets/components/SpinnerV2.scss
Normal 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%;
|
||||
}
|
||||
}
|
|
@ -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';
|
||||
|
|
|
@ -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} />;
|
||||
}
|
||||
|
|
|
@ -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" />
|
||||
|
|
40
ts/components/SpinnerV2.tsx
Normal file
40
ts/components/SpinnerV2.tsx
Normal 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>
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue