Skip to content

Commit 1c3d6ab

Browse files
feat: microphone preConnectBuffer is configurable (#182)
1 parent d8a0190 commit 1c3d6ab

4 files changed

Lines changed: 40 additions & 39 deletions

File tree

app-config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const APP_CONFIG_DEFAULTS: AppConfig = {
88
supportsChatInput: true,
99
supportsVideoInput: true,
1010
supportsScreenShare: true,
11+
isPreConnectBufferEnabled: true,
1112

1213
logo: '/lk-logo.svg',
1314
accent: '#002cf2',

components/app.tsx

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,10 @@ interface AppProps {
1919
}
2020

2121
export function App({ appConfig }: AppProps) {
22+
const room = useMemo(() => new Room(), []);
2223
const [sessionStarted, setSessionStarted] = useState(false);
23-
const { supportsChatInput, supportsVideoInput, supportsScreenShare, startButtonText } = appConfig;
24-
25-
const capabilities = {
26-
supportsChatInput,
27-
supportsVideoInput,
28-
supportsScreenShare,
29-
};
30-
3124
const { connectionDetails, refreshConnectionDetails } = useConnectionDetails();
3225

33-
const room = useMemo(() => new Room(), []);
34-
3526
useEffect(() => {
3627
const onDisconnected = () => {
3728
setSessionStarted(false);
@@ -55,7 +46,7 @@ export function App({ appConfig }: AppProps) {
5546
if (sessionStarted && room.state === 'disconnected' && connectionDetails) {
5647
Promise.all([
5748
room.localParticipant.setMicrophoneEnabled(true, undefined, {
58-
preConnectBuffer: true,
49+
preConnectBuffer: appConfig.isPreConnectBufferEnabled,
5950
}),
6051
room.connect(connectionDetails.serverUrl, connectionDetails.participantToken),
6152
]).catch((error) => {
@@ -68,7 +59,9 @@ export function App({ appConfig }: AppProps) {
6859
return () => {
6960
room.disconnect();
7061
};
71-
}, [room, sessionStarted, connectionDetails]);
62+
}, [room, sessionStarted, connectionDetails, appConfig.isPreConnectBufferEnabled]);
63+
64+
const { startButtonText } = appConfig;
7265

7366
return (
7467
<>
@@ -88,8 +81,8 @@ export function App({ appConfig }: AppProps) {
8881
{/* --- */}
8982
<MotionSessionView
9083
key="session-view"
84+
appConfig={appConfig}
9185
disabled={!sessionStarted}
92-
capabilities={capabilities}
9386
sessionStarted={sessionStarted}
9487
initial={{ opacity: 0 }}
9588
animate={{ opacity: sessionStarted ? 1 : 0 }}

components/session-view.tsx

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,22 @@ import { ChatMessageView } from '@/components/livekit/chat/chat-message-view';
1515
import { MediaTiles } from '@/components/livekit/media-tiles';
1616
import useChatAndTranscription from '@/hooks/useChatAndTranscription';
1717
import { useDebugMode } from '@/hooks/useDebug';
18+
import type { AppConfig } from '@/lib/types';
1819
import { cn } from '@/lib/utils';
1920

2021
function isAgentAvailable(agentState: AgentState) {
2122
return agentState == 'listening' || agentState == 'thinking' || agentState == 'speaking';
2223
}
2324

2425
interface SessionViewProps {
26+
appConfig: AppConfig;
2527
disabled: boolean;
26-
capabilities: {
27-
supportsChatInput: boolean;
28-
supportsVideoInput: boolean;
29-
supportsScreenShare: boolean;
30-
};
3128
sessionStarted: boolean;
3229
}
3330

3431
export const SessionView = ({
32+
appConfig,
3533
disabled,
36-
capabilities,
3734
sessionStarted,
3835
ref,
3936
}: React.ComponentProps<'div'> & SessionViewProps) => {
@@ -82,6 +79,13 @@ export const SessionView = ({
8279
}
8380
}, [agentState, sessionStarted, room]);
8481

82+
const { supportsChatInput, supportsVideoInput, supportsScreenShare } = appConfig;
83+
const capabilities = {
84+
supportsChatInput,
85+
supportsVideoInput,
86+
supportsScreenShare,
87+
};
88+
8589
return (
8690
<main
8791
ref={ref}
@@ -133,26 +137,28 @@ export const SessionView = ({
133137
transition={{ duration: 0.3, delay: sessionStarted ? 0.5 : 0, ease: 'easeOut' }}
134138
>
135139
<div className="relative z-10 mx-auto w-full max-w-2xl">
136-
<motion.div
137-
initial={{ opacity: 0 }}
138-
animate={{
139-
opacity: sessionStarted && messages.length === 0 ? 1 : 0,
140-
transition: {
141-
ease: 'easeIn',
142-
delay: messages.length > 0 ? 0 : 0.8,
143-
duration: messages.length > 0 ? 0.2 : 0.5,
144-
},
145-
}}
146-
aria-hidden={messages.length > 0}
147-
className={cn(
148-
'absolute inset-x-0 -top-12 text-center',
149-
sessionStarted && messages.length === 0 && 'pointer-events-none'
150-
)}
151-
>
152-
<p className="animate-text-shimmer inline-block !bg-clip-text text-sm font-semibold text-transparent">
153-
Agent is listening, ask it a question
154-
</p>
155-
</motion.div>
140+
{appConfig.isPreConnectBufferEnabled && (
141+
<motion.div
142+
initial={{ opacity: 0 }}
143+
animate={{
144+
opacity: sessionStarted && messages.length === 0 ? 1 : 0,
145+
transition: {
146+
ease: 'easeIn',
147+
delay: messages.length > 0 ? 0 : 0.8,
148+
duration: messages.length > 0 ? 0.2 : 0.5,
149+
},
150+
}}
151+
aria-hidden={messages.length > 0}
152+
className={cn(
153+
'absolute inset-x-0 -top-12 text-center',
154+
sessionStarted && messages.length === 0 && 'pointer-events-none'
155+
)}
156+
>
157+
<p className="animate-text-shimmer inline-block !bg-clip-text text-sm font-semibold text-transparent">
158+
Agent is listening, ask it a question
159+
</p>
160+
</motion.div>
161+
)}
156162

157163
<AgentControlBar
158164
capabilities={capabilities}

lib/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface AppConfig {
1515
supportsChatInput: boolean;
1616
supportsVideoInput: boolean;
1717
supportsScreenShare: boolean;
18+
isPreConnectBufferEnabled: boolean;
1819

1920
logo: string;
2021
startButtonText: string;

0 commit comments

Comments
 (0)