diff --git a/components/app.tsx b/components/app.tsx
index 725170b2..1e76c88e 100644
--- a/components/app.tsx
+++ b/components/app.tsx
@@ -1,9 +1,15 @@
'use client';
-import { useEffect, useMemo, useState } from 'react';
+import { useCallback, useEffect, useMemo, useState } from 'react';
import { Room, RoomEvent } from 'livekit-client';
import { motion } from 'motion/react';
-import { RoomAudioRenderer, RoomContext, StartAudio } from '@livekit/components-react';
+import {
+ LiveKitRoom,
+ RoomAudioRenderer,
+ RoomContext,
+ StartAudio,
+ useRoomConnection,
+} from '@livekit/components-react';
import { toastAlert } from '@/components/alert-toast';
import { SessionView } from '@/components/session-view';
import { Toaster } from '@/components/ui/sonner';
@@ -19,58 +25,25 @@ interface AppProps {
}
export function App({ appConfig }: AppProps) {
- const room = useMemo(() => new Room(), []);
const [sessionStarted, setSessionStarted] = useState(false);
const { connectionDetails, refreshConnectionDetails } = useConnectionDetails();
- useEffect(() => {
- const onDisconnected = () => {
- setSessionStarted(false);
- refreshConnectionDetails();
- };
- const onMediaDevicesError = (error: Error) => {
- toastAlert({
- title: 'Encountered an error with your media devices',
- description: `${error.name}: ${error.message}`,
- });
- };
- room.on(RoomEvent.MediaDevicesError, onMediaDevicesError);
- room.on(RoomEvent.Disconnected, onDisconnected);
- return () => {
- room.off(RoomEvent.Disconnected, onDisconnected);
- room.off(RoomEvent.MediaDevicesError, onMediaDevicesError);
- };
- }, [room, refreshConnectionDetails]);
+ const enableMicrophonePreConnectBuffer = useCallback(async (room: Room) => {
+ room.localParticipant.setMicrophoneEnabled(true, undefined, {
+ preConnectBuffer: appConfig.isPreConnectBufferEnabled,
+ });
+ }, []);
- useEffect(() => {
- let aborted = false;
- if (sessionStarted && room.state === 'disconnected' && connectionDetails) {
- Promise.all([
- room.localParticipant.setMicrophoneEnabled(true, undefined, {
- preConnectBuffer: appConfig.isPreConnectBufferEnabled,
- }),
- room.connect(connectionDetails.serverUrl, connectionDetails.participantToken),
- ]).catch((error) => {
- if (aborted) {
- // Once the effect has cleaned up after itself, drop any errors
- //
- // These errors are likely caused by this effect rerunning rapidly,
- // resulting in a previous run `disconnect` running in parallel with
- // a current run `connect`
- return;
- }
-
- toastAlert({
- title: 'There was an error connecting to the agent',
- description: `${error.name}: ${error.message}`,
- });
- });
- }
- return () => {
- aborted = true;
- room.disconnect();
- };
- }, [room, sessionStarted, connectionDetails, appConfig.isPreConnectBufferEnabled]);
+ const onDisconnected = useCallback(() => {
+ setSessionStarted(false);
+ refreshConnectionDetails();
+ }, [refreshConnectionDetails]);
+ const onMediaDeviceFailure = useCallback((error: Error) => {
+ toastAlert({
+ title: 'Encountered an error with your media devices',
+ description: `${error.name}: ${error.message}`,
+ });
+ }, []);
const { startButtonText } = appConfig;
@@ -86,7 +59,14 @@ export function App({ appConfig }: AppProps) {
transition={{ duration: 0.5, ease: 'linear', delay: sessionStarted ? 0 : 0.5 }}
/>
-
+
{/* --- */}
@@ -103,7 +83,7 @@ export function App({ appConfig }: AppProps) {
delay: sessionStarted ? 0.5 : 0,
}}
/>
-
+
>