Add own control buttons for element-call (#2744)
* add mutation observer hok * add hook to read speaking member by observing iframe content * display speaking member name in call status bar and improve layout * fix shrining * add joined call control bar * remove chat toggle from room header * change member speaking icon to mic * fix joined call control appear in other * show spinner on end call button * hide call statusbar for mobile view when room is selected * make call statusbar more mobile friendly * fix call status bar item align
This commit is contained in:
parent
55e8306576
commit
bc6caddcc8
17 changed files with 521 additions and 100 deletions
|
|
@ -1,7 +1,8 @@
|
|||
import { Box, Chip, Icon, IconButton, Icons, Text, Tooltip, TooltipProvider } from 'folds';
|
||||
import React, { useState } from 'react';
|
||||
import { Box, Chip, Icon, IconButton, Icons, Spinner, Text, Tooltip, TooltipProvider } from 'folds';
|
||||
import React, { useCallback } from 'react';
|
||||
import { StatusDivider } from './components';
|
||||
import { CallEmbed, useCallControlState } from '../../plugins/call';
|
||||
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
|
||||
|
||||
type MicrophoneButtonProps = {
|
||||
enabled: boolean;
|
||||
|
|
@ -104,9 +105,11 @@ function VideoButton({ enabled, onToggle }: VideoButtonProps) {
|
|||
);
|
||||
}
|
||||
|
||||
function ScreenShareButton() {
|
||||
const [enabled, setEnabled] = useState(false);
|
||||
|
||||
type ScreenShareButtonProps = {
|
||||
enabled: boolean;
|
||||
onToggle: () => void;
|
||||
};
|
||||
function ScreenShareButton({ enabled, onToggle }: ScreenShareButtonProps) {
|
||||
return (
|
||||
<TooltipProvider
|
||||
position="Top"
|
||||
|
|
@ -123,7 +126,7 @@ function ScreenShareButton() {
|
|||
fill="Soft"
|
||||
radii="300"
|
||||
size="300"
|
||||
onClick={() => setEnabled(!enabled)}
|
||||
onClick={onToggle}
|
||||
outlined
|
||||
>
|
||||
<Icon size="100" src={Icons.ScreenShare} filled={enabled} />
|
||||
|
|
@ -133,8 +136,14 @@ function ScreenShareButton() {
|
|||
);
|
||||
}
|
||||
|
||||
export function CallControl({ callEmbed }: { callEmbed: CallEmbed }) {
|
||||
const { microphone, video, sound } = useCallControlState(callEmbed.control);
|
||||
export function CallControl({ callEmbed, compact }: { callEmbed: CallEmbed; compact: boolean }) {
|
||||
const { microphone, video, sound, screenshare } = useCallControlState(callEmbed.control);
|
||||
|
||||
const [hangupState, hangup] = useAsyncCallback(
|
||||
useCallback(() => callEmbed.hangup(), [callEmbed])
|
||||
);
|
||||
const exiting =
|
||||
hangupState.status === AsyncStatus.Loading || hangupState.status === AsyncStatus.Success;
|
||||
|
||||
return (
|
||||
<Box shrink="No" alignItems="Center" gap="300">
|
||||
|
|
@ -144,21 +153,36 @@ export function CallControl({ callEmbed }: { callEmbed: CallEmbed }) {
|
|||
onToggle={() => callEmbed.control.toggleMicrophone()}
|
||||
/>
|
||||
<SoundButton enabled={sound} onToggle={() => callEmbed.control.toggleSound()} />
|
||||
{!compact && <StatusDivider />}
|
||||
<VideoButton enabled={video} onToggle={() => callEmbed.control.toggleVideo()} />
|
||||
{false && <ScreenShareButton />}
|
||||
{!compact && (
|
||||
<ScreenShareButton
|
||||
enabled={screenshare}
|
||||
onToggle={() => callEmbed.control.toggleScreenshare()}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
<StatusDivider />
|
||||
<Chip
|
||||
variant="Critical"
|
||||
radii="300"
|
||||
radii="Pill"
|
||||
fill="Soft"
|
||||
before={<Icon size="50" src={Icons.PhoneDown} filled />}
|
||||
before={
|
||||
exiting ? (
|
||||
<Spinner variant="Critical" fill="Soft" size="50" />
|
||||
) : (
|
||||
<Icon size="50" src={Icons.PhoneDown} filled />
|
||||
)
|
||||
}
|
||||
disabled={exiting}
|
||||
outlined
|
||||
onClick={() => callEmbed.hangup()}
|
||||
onClick={hangup}
|
||||
>
|
||||
<Text as="span" size="L400">
|
||||
End
|
||||
</Text>
|
||||
{!compact && (
|
||||
<Text as="span" size="L400">
|
||||
End
|
||||
</Text>
|
||||
)}
|
||||
</Chip>
|
||||
</Box>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -47,18 +47,17 @@ export function CallStatus({ callEmbed }: CallStatusProps) {
|
|||
) : (
|
||||
<Spinner variant="Secondary" size="200" />
|
||||
)}
|
||||
<Box
|
||||
grow="Yes"
|
||||
alignItems="Center"
|
||||
gap="Inherit"
|
||||
justifyContent={compact ? 'Center' : undefined}
|
||||
>
|
||||
<CallRoomName room={room} />
|
||||
{speakers.size > 0 && !compact && (
|
||||
<Box grow="Yes" alignItems="Center" gap="Inherit">
|
||||
{!compact && (
|
||||
<>
|
||||
<StatusDivider />
|
||||
<span data-spacing-node />
|
||||
<MemberSpeaking room={room} speakers={speakers} />
|
||||
<CallRoomName room={room} />
|
||||
{speakers.size > 0 && (
|
||||
<>
|
||||
<StatusDivider />
|
||||
<span data-spacing-node />
|
||||
<MemberSpeaking room={room} speakers={speakers} />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
|
|
@ -69,8 +68,13 @@ export function CallStatus({ callEmbed }: CallStatusProps) {
|
|||
)}
|
||||
</Box>
|
||||
{memberVisible && !compact && <StatusDivider />}
|
||||
<Box shrink="No" alignItems="Center" justifyContent="Center" gap="Inherit">
|
||||
<CallControl callEmbed={callEmbed} />
|
||||
<Box shrink="No" alignItems="Center" gap="Inherit">
|
||||
{compact && (
|
||||
<Box grow="Yes">
|
||||
<CallRoomName room={room} />
|
||||
</Box>
|
||||
)}
|
||||
<CallControl compact={compact} callEmbed={callEmbed} />
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ export function LiveChip({ count, room, members }: LiveChipProps) {
|
|||
radii="Pill"
|
||||
onClick={handleOpenMenu}
|
||||
>
|
||||
<Text className={css.LiveChipText} as="span" size="L400">
|
||||
<Text className={css.LiveChipText} as="span" size="L400" truncate>
|
||||
{count} Live
|
||||
</Text>
|
||||
</Chip>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export function MemberSpeaking({ room, speakers }: MemberSpeakingProps) {
|
|||
);
|
||||
return (
|
||||
<Box alignItems="Center" gap="100">
|
||||
<Icon size="100" src={Icons.Phone} filled />
|
||||
<Icon size="100" src={Icons.Mic} filled />
|
||||
<Text size="T200" truncate>
|
||||
{speakingNames.length === 1 && (
|
||||
<>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue