/**
* VoiceVideoCall Component
* Displays voice/video call interface with participant videos and controls
*/
import React, { useEffect, useState } from 'react';
import {
LiveKitRoom,
VideoConference,
GridLayout,
ParticipantTile,
useRemoteParticipant,
useLocalParticipant,
} from 'livekit-react';
import './VoiceVideoCall.css';
export default function VoiceVideoCall({
roomName,
userName,
token,
serverUrl,
onLeave,
}) {
const [callState, setCallState] = useState('connecting'); // connecting, connected, ended
if (!token || !serverUrl) {
return (
Missing required configuration for video call
);
}
return (
setCallState('connected')}
onDisconnected={() => {
setCallState('ended');
onLeave?.();
}}
options={{
adaptiveStream: true,
dynacast: true,
}}
>
{callState === 'connecting' && (
Connecting to {roomName}...
)}
{callState === 'connected' && (
<>
>
)}
);
}
/**
* CallControls Component
* Displays microphone, camera, screen share, and leave buttons
*/
function CallControls({ onLeave }) {
const { localParticipant } = useLocalParticipant();
const [isMuted, setIsMuted] = useState(false);
const [isCameraOff, setIsCameraOff] = useState(false);
const [isScreenSharing, setIsScreenSharing] = useState(false);
const handleToggleMicrophone = async () => {
await localParticipant?.setMicrophoneEnabled(isMuted);
setIsMuted(!isMuted);
};
const handleToggleCamera = async () => {
await localParticipant?.setCameraEnabled(isCameraOff);
setIsCameraOff(!isCameraOff);
};
const handleToggleScreenShare = async () => {
await localParticipant?.setScreenShareEnabled(!isScreenSharing);
setIsScreenSharing(!isScreenSharing);
};
return (
);
}