Show call support error and disable join button (#2748)
* allow user to end call if error when loading * show call support missing error if livekit server is not provided * prevent joining from nav item double click if no livekit support
This commit is contained in:
parent
2eb5a9a616
commit
4449e7c6e8
9 changed files with 220 additions and 62 deletions
|
|
@ -1,14 +1,17 @@
|
|||
import { Box, Chip, Icon, IconButton, Icons, Spinner, Text, Tooltip, TooltipProvider } from 'folds';
|
||||
import React, { useCallback } from 'react';
|
||||
import { useSetAtom } from 'jotai';
|
||||
import { StatusDivider } from './components';
|
||||
import { CallEmbed, useCallControlState } from '../../plugins/call';
|
||||
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
|
||||
import { callEmbedAtom } from '../../state/callEmbed';
|
||||
|
||||
type MicrophoneButtonProps = {
|
||||
enabled: boolean;
|
||||
onToggle: () => Promise<unknown>;
|
||||
disabled?: boolean;
|
||||
};
|
||||
function MicrophoneButton({ enabled, onToggle }: MicrophoneButtonProps) {
|
||||
function MicrophoneButton({ enabled, onToggle, disabled }: MicrophoneButtonProps) {
|
||||
return (
|
||||
<TooltipProvider
|
||||
position="Top"
|
||||
|
|
@ -27,6 +30,7 @@ function MicrophoneButton({ enabled, onToggle }: MicrophoneButtonProps) {
|
|||
size="300"
|
||||
onClick={() => onToggle()}
|
||||
outlined
|
||||
disabled={disabled}
|
||||
>
|
||||
<Icon size="100" src={enabled ? Icons.Mic : Icons.MicMute} filled={!enabled} />
|
||||
</IconButton>
|
||||
|
|
@ -38,8 +42,9 @@ function MicrophoneButton({ enabled, onToggle }: MicrophoneButtonProps) {
|
|||
type SoundButtonProps = {
|
||||
enabled: boolean;
|
||||
onToggle: () => void;
|
||||
disabled?: boolean;
|
||||
};
|
||||
function SoundButton({ enabled, onToggle }: SoundButtonProps) {
|
||||
function SoundButton({ enabled, onToggle, disabled }: SoundButtonProps) {
|
||||
return (
|
||||
<TooltipProvider
|
||||
position="Top"
|
||||
|
|
@ -58,6 +63,7 @@ function SoundButton({ enabled, onToggle }: SoundButtonProps) {
|
|||
size="300"
|
||||
onClick={() => onToggle()}
|
||||
outlined
|
||||
disabled={disabled}
|
||||
>
|
||||
<Icon
|
||||
size="100"
|
||||
|
|
@ -73,8 +79,9 @@ function SoundButton({ enabled, onToggle }: SoundButtonProps) {
|
|||
type VideoButtonProps = {
|
||||
enabled: boolean;
|
||||
onToggle: () => Promise<unknown>;
|
||||
disabled?: boolean;
|
||||
};
|
||||
function VideoButton({ enabled, onToggle }: VideoButtonProps) {
|
||||
function VideoButton({ enabled, onToggle, disabled }: VideoButtonProps) {
|
||||
return (
|
||||
<TooltipProvider
|
||||
position="Top"
|
||||
|
|
@ -93,6 +100,7 @@ function VideoButton({ enabled, onToggle }: VideoButtonProps) {
|
|||
size="300"
|
||||
onClick={() => onToggle()}
|
||||
outlined
|
||||
disabled={disabled}
|
||||
>
|
||||
<Icon
|
||||
size="100"
|
||||
|
|
@ -108,8 +116,9 @@ function VideoButton({ enabled, onToggle }: VideoButtonProps) {
|
|||
type ScreenShareButtonProps = {
|
||||
enabled: boolean;
|
||||
onToggle: () => void;
|
||||
disabled?: boolean;
|
||||
};
|
||||
function ScreenShareButton({ enabled, onToggle }: ScreenShareButtonProps) {
|
||||
function ScreenShareButton({ enabled, onToggle, disabled }: ScreenShareButtonProps) {
|
||||
return (
|
||||
<TooltipProvider
|
||||
position="Top"
|
||||
|
|
@ -128,6 +137,7 @@ function ScreenShareButton({ enabled, onToggle }: ScreenShareButtonProps) {
|
|||
size="300"
|
||||
onClick={onToggle}
|
||||
outlined
|
||||
disabled={disabled}
|
||||
>
|
||||
<Icon size="100" src={Icons.ScreenShare} filled={enabled} />
|
||||
</IconButton>
|
||||
|
|
@ -136,8 +146,17 @@ function ScreenShareButton({ enabled, onToggle }: ScreenShareButtonProps) {
|
|||
);
|
||||
}
|
||||
|
||||
export function CallControl({ callEmbed, compact }: { callEmbed: CallEmbed; compact: boolean }) {
|
||||
export function CallControl({
|
||||
callEmbed,
|
||||
compact,
|
||||
callJoined,
|
||||
}: {
|
||||
callEmbed: CallEmbed;
|
||||
compact: boolean;
|
||||
callJoined: boolean;
|
||||
}) {
|
||||
const { microphone, video, sound, screenshare } = useCallControlState(callEmbed.control);
|
||||
const setCallEmbed = useSetAtom(callEmbedAtom);
|
||||
|
||||
const [hangupState, hangup] = useAsyncCallback(
|
||||
useCallback(() => callEmbed.hangup(), [callEmbed])
|
||||
|
|
@ -145,20 +164,38 @@ export function CallControl({ callEmbed, compact }: { callEmbed: CallEmbed; comp
|
|||
const exiting =
|
||||
hangupState.status === AsyncStatus.Loading || hangupState.status === AsyncStatus.Success;
|
||||
|
||||
const handleHangup = () => {
|
||||
if (!callJoined) {
|
||||
setCallEmbed(undefined);
|
||||
return;
|
||||
}
|
||||
hangup();
|
||||
};
|
||||
|
||||
return (
|
||||
<Box shrink="No" alignItems="Center" gap="300">
|
||||
<Box alignItems="Inherit" gap="200">
|
||||
<MicrophoneButton
|
||||
enabled={microphone}
|
||||
onToggle={() => callEmbed.control.toggleMicrophone()}
|
||||
disabled={!callJoined}
|
||||
/>
|
||||
<SoundButton
|
||||
enabled={sound}
|
||||
onToggle={() => callEmbed.control.toggleSound()}
|
||||
disabled={!callJoined}
|
||||
/>
|
||||
<SoundButton enabled={sound} onToggle={() => callEmbed.control.toggleSound()} />
|
||||
{!compact && <StatusDivider />}
|
||||
<VideoButton enabled={video} onToggle={() => callEmbed.control.toggleVideo()} />
|
||||
<VideoButton
|
||||
enabled={video}
|
||||
onToggle={() => callEmbed.control.toggleVideo()}
|
||||
disabled={!callJoined}
|
||||
/>
|
||||
{!compact && (
|
||||
<ScreenShareButton
|
||||
enabled={screenshare}
|
||||
onToggle={() => callEmbed.control.toggleScreenshare()}
|
||||
disabled={!callJoined}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
|
@ -176,7 +213,7 @@ export function CallControl({ callEmbed, compact }: { callEmbed: CallEmbed; comp
|
|||
}
|
||||
disabled={exiting}
|
||||
outlined
|
||||
onClick={hangup}
|
||||
onClick={handleHangup}
|
||||
>
|
||||
{!compact && (
|
||||
<Text as="span" size="L400">
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ export function CallStatus({ callEmbed }: CallStatusProps) {
|
|||
<CallRoomName room={room} />
|
||||
</Box>
|
||||
)}
|
||||
<CallControl compact={compact} callEmbed={callEmbed} />
|
||||
<CallControl callJoined={callJoined} compact={compact} callEmbed={callEmbed} />
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue