Update call lobby UI to match new designs
This commit is contained in:
parent
50c4fa06cc
commit
763c35e546
26 changed files with 857 additions and 435 deletions
107
ts/components/CallingLobbyJoinButton.tsx
Normal file
107
ts/components/CallingLobbyJoinButton.tsx
Normal file
|
@ -0,0 +1,107 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { FunctionComponent, ReactChild, useState } from 'react';
|
||||
import { noop } from 'lodash';
|
||||
|
||||
import type { LocalizerType } from '../types/Util';
|
||||
import { Button, ButtonVariant } from './Button';
|
||||
import { Spinner } from './Spinner';
|
||||
|
||||
const PADDING_HORIZONTAL = 48;
|
||||
const PADDING_VERTICAL = 12;
|
||||
|
||||
export enum CallingLobbyJoinButtonVariant {
|
||||
CallIsFull = 'CallIsFull',
|
||||
Join = 'Join',
|
||||
Loading = 'Loading',
|
||||
Start = 'Start',
|
||||
}
|
||||
|
||||
/**
|
||||
* This component is a little weird. Why not just render a button with some children?
|
||||
*
|
||||
* The contents of this component can change but we don't want its size to change, so we
|
||||
* render all the variants invisibly, compute the maximum size, and then render the
|
||||
* "final" button with those dimensions.
|
||||
*
|
||||
* For example, we might initially render "Join call" and then render a spinner when you
|
||||
* click the button. The button shouldn't resize in that situation.
|
||||
*/
|
||||
export const CallingLobbyJoinButton: FunctionComponent<{
|
||||
disabled?: boolean;
|
||||
i18n: LocalizerType;
|
||||
onClick: () => void;
|
||||
variant: CallingLobbyJoinButtonVariant;
|
||||
}> = ({ disabled, i18n, onClick, variant }) => {
|
||||
const [width, setWidth] = useState<undefined | number>();
|
||||
const [height, setHeight] = useState<undefined | number>();
|
||||
|
||||
const childrenByVariant: Record<CallingLobbyJoinButtonVariant, ReactChild> = {
|
||||
[CallingLobbyJoinButtonVariant.CallIsFull]: i18n('calling__call-is-full'),
|
||||
[CallingLobbyJoinButtonVariant.Loading]: <Spinner svgSize="small" />,
|
||||
[CallingLobbyJoinButtonVariant.Join]: i18n('calling__join'),
|
||||
[CallingLobbyJoinButtonVariant.Start]: i18n('calling__start'),
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{Boolean(width && height) && (
|
||||
<Button
|
||||
className="module-CallingLobbyJoinButton"
|
||||
disabled={disabled}
|
||||
onClick={onClick}
|
||||
style={{ width, height }}
|
||||
tabIndex={0}
|
||||
variant={ButtonVariant.Calling}
|
||||
>
|
||||
{childrenByVariant[variant]}
|
||||
</Button>
|
||||
)}
|
||||
<div
|
||||
style={{
|
||||
visibility: 'hidden',
|
||||
position: 'fixed',
|
||||
left: -9999,
|
||||
top: -9999,
|
||||
}}
|
||||
>
|
||||
{Object.values(CallingLobbyJoinButtonVariant).map(candidateVariant => (
|
||||
<Button
|
||||
key={candidateVariant}
|
||||
className="module-CallingLobbyJoinButton"
|
||||
variant={ButtonVariant.Calling}
|
||||
onClick={noop}
|
||||
ref={(button: HTMLButtonElement | null) => {
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
const {
|
||||
width: variantWidth,
|
||||
height: variantHeight,
|
||||
} = button.getBoundingClientRect();
|
||||
|
||||
// We could set the padding in CSS, but we don't do that in case some other
|
||||
// styling causes a re-render of the button but not of the component. This
|
||||
// is easiest to reproduce in Storybook, where the font hasn't loaded yet;
|
||||
// we compute the size, then the font makes the text a bit larger, and
|
||||
// there's a layout issue.
|
||||
setWidth((previousWidth = 0) =>
|
||||
Math.ceil(
|
||||
Math.max(previousWidth, variantWidth + PADDING_HORIZONTAL)
|
||||
)
|
||||
);
|
||||
setHeight((previousHeight = 0) =>
|
||||
Math.ceil(
|
||||
Math.max(previousHeight, variantHeight + PADDING_VERTICAL)
|
||||
)
|
||||
);
|
||||
}}
|
||||
>
|
||||
{childrenByVariant[candidateVariant]}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue