Skip to content

Commit 70eaa94

Browse files
cleanup demo code
1 parent ea71b77 commit 70eaa94

18 files changed

+1185
-1054
lines changed

app/ui/_components.tsx

Lines changed: 30 additions & 1051 deletions
Large diffs are not rendered by default.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { useMicrophone } from '@/app/ui/_components';
2+
import { Container } from '../docs/container';
3+
import { AgentControlBar } from '../livekit/agent-control-bar/agent-control-bar';
4+
5+
export default function AgentControlBarDemo() {
6+
useMicrophone();
7+
8+
return (
9+
<Container componentName="AgentControlBar">
10+
<div className="relative flex items-center justify-center">
11+
<AgentControlBar
12+
className="w-full"
13+
controls={{
14+
leave: true,
15+
chat: true,
16+
camera: true,
17+
microphone: true,
18+
screenShare: true,
19+
}}
20+
/>
21+
</div>
22+
</Container>
23+
);
24+
}

components/demos/Alert.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { type VariantProps } from 'class-variance-authority';
2+
import { Container } from '@/components/docs/container';
3+
import { StoryTitle } from '@/components/docs/story-title';
4+
import { Alert, AlertDescription, AlertTitle, alertVariants } from '@/components/livekit/alert';
5+
6+
type alertVariantsType = VariantProps<typeof alertVariants>['variant'];
7+
8+
export default function AlertDemo() {
9+
return (
10+
<Container componentName="Alert">
11+
{['default', 'destructive'].map((variant) => (
12+
<div key={variant}>
13+
<StoryTitle>{variant}</StoryTitle>
14+
<Alert key={variant} variant={variant as alertVariantsType}>
15+
<AlertTitle>Alert {variant} title</AlertTitle>
16+
<AlertDescription>This is a {variant} alert description.</AlertDescription>
17+
</Alert>
18+
</div>
19+
))}
20+
</Container>
21+
);
22+
}

components/demos/AlertToast.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Container } from '../docs/container';
2+
import { StoryTitle } from '../docs/story-title';
3+
import { AlertToast } from '../livekit/alert-toast';
4+
5+
export default function AlertToastDemo() {
6+
return (
7+
<Container componentName="AlertToast">
8+
<StoryTitle>Alert toast</StoryTitle>
9+
<div className="mx-auto max-w-prose">
10+
<AlertToast
11+
id="alert-toast"
12+
title="Alert toast"
13+
description="This is a alert toast description."
14+
/>
15+
</div>
16+
</Container>
17+
);
18+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import { useMemo, useState } from 'react';
2+
import { type VariantProps } from 'class-variance-authority';
3+
import { Track } from 'livekit-client';
4+
import {
5+
type AgentState,
6+
type TrackReference,
7+
type TrackReferenceOrPlaceholder,
8+
useLocalParticipant,
9+
} from '@livekit/components-react';
10+
import { useMicrophone } from '@/app/ui/_components';
11+
import { Container } from '@/components/docs/container';
12+
import {
13+
AudioBarVisualizer,
14+
audioBarVisualizerVariants,
15+
} from '@/components/livekit/audio-visualizer/audio-bar-visualizer/audio-bar-visualizer';
16+
import { Button } from '@/components/livekit/button';
17+
import {
18+
Select,
19+
SelectContent,
20+
SelectItem,
21+
SelectTrigger,
22+
SelectValue,
23+
} from '@/components/livekit/select';
24+
25+
type audioBarVisualizerVariantsSizeType = VariantProps<typeof audioBarVisualizerVariants>['size'];
26+
27+
export default function AudioBarVisualizerDemo() {
28+
const barCounts = ['0', '3', '5', '7', '9'];
29+
const sizes = ['icon', 'sm', 'md', 'lg', 'xl'];
30+
const states = [
31+
'disconnected',
32+
'connecting',
33+
'initializing',
34+
'listening',
35+
'thinking',
36+
'speaking',
37+
] as AgentState[];
38+
39+
const { microphoneTrack, localParticipant } = useLocalParticipant();
40+
const [barCount, setBarCount] = useState<string>(barCounts[0]);
41+
const [size, setSize] = useState<audioBarVisualizerVariantsSizeType>(
42+
'md' as audioBarVisualizerVariantsSizeType
43+
);
44+
const [state, setState] = useState<AgentState>(states[0]);
45+
46+
const micTrackRef = useMemo<TrackReferenceOrPlaceholder | undefined>(() => {
47+
return state === 'speaking'
48+
? ({
49+
participant: localParticipant,
50+
source: Track.Source.Microphone,
51+
publication: microphoneTrack,
52+
} as TrackReference)
53+
: undefined;
54+
}, [state, localParticipant, microphoneTrack]);
55+
56+
useMicrophone();
57+
58+
return (
59+
<Container componentName="AudioVisualizer">
60+
<div className="flex items-center gap-2">
61+
<div className="flex-1">
62+
<label className="font-mono text-xs uppercase" htmlFor="size">
63+
Size
64+
</label>
65+
<Select
66+
value={size as string}
67+
onValueChange={(value) => setSize(value as audioBarVisualizerVariantsSizeType)}
68+
>
69+
<SelectTrigger id="size" className="w-full">
70+
<SelectValue placeholder="Select a size" />
71+
</SelectTrigger>
72+
<SelectContent>
73+
{sizes.map((size) => (
74+
<SelectItem key={size} value={size as string}>
75+
{size.toUpperCase()}
76+
</SelectItem>
77+
))}
78+
</SelectContent>
79+
</Select>
80+
</div>
81+
82+
<div className="flex-1">
83+
<label className="font-mono text-xs uppercase" htmlFor="barCount">
84+
Bar count
85+
</label>
86+
<Select value={barCount.toString()} onValueChange={(value) => setBarCount(value)}>
87+
<SelectTrigger id="barCount" className="w-full">
88+
<SelectValue placeholder="Select a bar count" />
89+
</SelectTrigger>
90+
<SelectContent>
91+
{barCounts.map((barCount) => (
92+
<SelectItem key={barCount} value={barCount.toString()}>
93+
{parseInt(barCount) || 'Default'}
94+
</SelectItem>
95+
))}
96+
</SelectContent>
97+
</Select>
98+
</div>
99+
</div>
100+
101+
<div className="relative flex flex-col justify-center gap-4">
102+
<div className="grid place-items-center py-8">
103+
<AudioBarVisualizer
104+
size={size as audioBarVisualizerVariantsSizeType}
105+
state={state}
106+
audioTrack={micTrackRef!}
107+
barCount={parseInt(barCount) || undefined}
108+
className="mx-auto"
109+
>
110+
<div className="data-[lk-highlighted=true]:!bg-primary rounded-full" />
111+
</AudioBarVisualizer>
112+
</div>
113+
{/* <details>
114+
<summary className="text-muted-foreground font-mono text-xs uppercase">
115+
<span className="inline-block cursor-pointer p-1">Original BarVisualizer</span>
116+
</summary>
117+
<div className="border-border grid place-items-center rounded-xl border p-4 py-8">
118+
<BarVisualizer
119+
size={size as audioBarVisualizerVariantsSizeType}
120+
state={state}
121+
audioTrack={micTrackRef!}
122+
barCount={parseInt(barCount) || undefined}
123+
className="mx-auto"
124+
/>
125+
</div>
126+
</details> */}
127+
</div>
128+
129+
<div className="flex flex-wrap gap-4">
130+
{states.map((stateType) => (
131+
<Button
132+
key={stateType}
133+
size="sm"
134+
variant={state === stateType ? 'primary' : 'default'}
135+
onClick={() => setState(stateType)}
136+
className={'flex-1'}
137+
>
138+
{stateType}
139+
</Button>
140+
))}
141+
</div>
142+
</Container>
143+
);
144+
}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import { useMemo, useState } from 'react';
2+
import { Track } from 'livekit-client';
3+
import { useLocalParticipant } from '@livekit/components-react';
4+
import {
5+
type AgentState,
6+
type TrackReference,
7+
type TrackReferenceOrPlaceholder,
8+
} from '@livekit/components-react';
9+
import { useMicrophone } from '@/app/ui/_components';
10+
import { Container } from '@/components/docs/container';
11+
import { StoryTitle } from '@/components/docs/story-title';
12+
import { AudioGridVisualizer } from '@/components/livekit/audio-visualizer/audio-grid-visualizer/audio-grid-visualizer';
13+
import { type GridOptions } from '@/components/livekit/audio-visualizer/audio-grid-visualizer/audio-grid-visualizer';
14+
import { gridVariants } from '@/components/livekit/audio-visualizer/audio-grid-visualizer/demos';
15+
import { Button } from '@/components/livekit/button';
16+
import {
17+
Select,
18+
SelectContent,
19+
SelectItem,
20+
SelectTrigger,
21+
SelectValue,
22+
} from '@/components/livekit/select';
23+
24+
export default function AudioGridVisualizerDemo() {
25+
const rowCounts = ['3', '5', '7', '9', '11', '13', '15'];
26+
const columnCounts = ['3', '5', '7', '9', '11', '13', '15'];
27+
const states = [
28+
'disconnected',
29+
'connecting',
30+
'initializing',
31+
'listening',
32+
'thinking',
33+
'speaking',
34+
] as AgentState[];
35+
36+
const [rowCount, setRowCount] = useState(rowCounts[0]);
37+
const [columnCount, setColumnCount] = useState(columnCounts[0]);
38+
const [state, setState] = useState<AgentState>(states[0]);
39+
const [demoIndex, setDemoIndex] = useState(0);
40+
const { microphoneTrack, localParticipant } = useLocalParticipant();
41+
42+
const micTrackRef = useMemo<TrackReferenceOrPlaceholder | undefined>(() => {
43+
return state === 'speaking'
44+
? ({
45+
participant: localParticipant,
46+
source: Track.Source.Microphone,
47+
publication: microphoneTrack,
48+
} as TrackReference)
49+
: undefined;
50+
}, [state, localParticipant, microphoneTrack]);
51+
52+
useMicrophone();
53+
54+
const demoOptions = {
55+
rowCount: parseInt(rowCount),
56+
columnCount: parseInt(columnCount),
57+
...gridVariants[demoIndex],
58+
};
59+
60+
return (
61+
<Container componentName="AudioVisualizer">
62+
<div className="flex items-center gap-2">
63+
<div className="flex-1">
64+
<label className="font-mono text-xs uppercase" htmlFor="rowCount">
65+
Row count
66+
</label>
67+
<Select value={rowCount.toString()} onValueChange={(value) => setRowCount(value)}>
68+
<SelectTrigger id="rowCount" className="w-full">
69+
<SelectValue placeholder="Select a bar count" />
70+
</SelectTrigger>
71+
<SelectContent>
72+
{rowCounts.map((rowCount) => (
73+
<SelectItem key={rowCount} value={rowCount.toString()}>
74+
{parseInt(rowCount) || 'Default'}
75+
</SelectItem>
76+
))}
77+
</SelectContent>
78+
</Select>
79+
</div>
80+
81+
<div className="flex-1">
82+
<label className="font-mono text-xs uppercase" htmlFor="columnCount">
83+
Column count
84+
</label>
85+
<Select value={columnCount.toString()} onValueChange={(value) => setColumnCount(value)}>
86+
<SelectTrigger id="columnCount" className="w-full">
87+
<SelectValue placeholder="Select a column count" />
88+
</SelectTrigger>
89+
<SelectContent>
90+
{columnCounts.map((columnCount) => (
91+
<SelectItem key={columnCount} value={columnCount.toString()}>
92+
{parseInt(columnCount) || 'Default'}
93+
</SelectItem>
94+
))}
95+
</SelectContent>
96+
</Select>
97+
</div>
98+
99+
<div className="flex-1">
100+
<label className="font-mono text-xs uppercase" htmlFor="demoIndex">
101+
Demo
102+
</label>
103+
<Select
104+
value={demoIndex.toString()}
105+
onValueChange={(value) => setDemoIndex(parseInt(value))}
106+
>
107+
<SelectTrigger id="demoIndex" className="w-full">
108+
<SelectValue placeholder="Select a demo" />
109+
</SelectTrigger>
110+
<SelectContent>
111+
{gridVariants.map((_, idx) => (
112+
<SelectItem key={idx} value={idx.toString()}>
113+
Demo {String(idx + 1)}
114+
</SelectItem>
115+
))}
116+
</SelectContent>
117+
</Select>
118+
</div>
119+
</div>
120+
121+
<div className="grid place-items-center py-12">
122+
<AudioGridVisualizer
123+
key={`${demoIndex}-${rowCount}-${columnCount}`}
124+
state={state}
125+
audioTrack={micTrackRef!}
126+
{...(demoOptions as GridOptions)}
127+
/>
128+
</div>
129+
130+
<div className="flex flex-wrap gap-4">
131+
{states.map((stateType) => (
132+
<Button
133+
key={stateType}
134+
size="sm"
135+
variant={state === stateType ? 'primary' : 'default'}
136+
onClick={() => setState(stateType)}
137+
className={'flex-1'}
138+
>
139+
{stateType}
140+
</Button>
141+
))}
142+
</div>
143+
144+
<div>
145+
<StoryTitle>Demo options</StoryTitle>
146+
<div className="border-border bg-muted overflow-x-auto rounded-xl border p-8">
147+
<pre className="text-muted-foreground text-sm">
148+
<code>{JSON.stringify(demoOptions, null, 2)}</code>
149+
</pre>
150+
</div>
151+
</div>
152+
</Container>
153+
);
154+
}

0 commit comments

Comments
 (0)