Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import React from 'react';
import { StoryObj } from '@storybook/react-vite';
import { useTheme } from 'next-themes';
import { AgentSessionProvider } from '../../.storybook/lk-decorators/AgentSessionProvider';
import { AgentSessionView_01, AgentSessionView_01Props } from '@agents-ui';

export default {
component: AgentSessionView_01,
decorators: [AgentSessionProvider],
render: (args: AgentSessionView_01Props) => <AgentSessionView_01 {...args} />,
render: (args: AgentSessionView_01Props) => {
const { resolvedTheme = 'dark' } = useTheme();
return (
<AgentSessionView_01 themeMode={resolvedTheme as 'dark' | 'light'} {...args} />
);
},
args: {
className: 'h-screen w-screen',
supportsChatInput: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ export function Fade({ top = false, bottom = false, className }: FadeProps) {
}

export interface AgentSessionView_01Props {
/**
* Theme mode forwarded to the aura visualizer (`audioVisualizerType="aura"`) so
* the shader's blend mode adapts to the theme mode.
* Ignored by other visualizer types.
*/
themeMode?: 'dark' | 'light';
/**
* Message shown above the controls before the first chat message is sent.
*
Expand Down Expand Up @@ -161,7 +167,6 @@ export function AgentSessionView_01({
supportsVideoInput = true,
supportsScreenShare = true,
isPreConnectBufferEnabled = true,

audioVisualizerType,
audioVisualizerColor,
audioVisualizerColorShift,
Expand All @@ -171,13 +176,14 @@ export function AgentSessionView_01({
audioVisualizerRadialBarCount,
audioVisualizerRadialRadius,
audioVisualizerWaveLineWidth,
themeMode,
ref,
className,
...props
}: React.ComponentProps<'section'> & AgentSessionView_01Props) {
const session = useSessionContext();
const { messages } = useSessionMessages(session);
const [chatOpen, setChatOpen] = useState(false);
const [isChatOpen, setIsChatOpen] = useState(false);
const scrollAreaRef = useRef<HTMLDivElement>(null);
const { state: agentState } = useAgent();

Expand Down Expand Up @@ -209,7 +215,7 @@ export function AgentSessionView_01({

<div className="absolute top-0 bottom-[135px] flex w-full flex-col md:bottom-[170px]">
<AnimatePresence>
{chatOpen && (
{isChatOpen && (
<motion.div
{...CHAT_MOTION_PROPS}
className="flex h-full w-full flex-col gap-4 space-y-3 transition-opacity duration-300 ease-out"
Expand All @@ -225,7 +231,8 @@ export function AgentSessionView_01({
</div>
{/* Tile layout */}
<TileLayout
chatOpen={chatOpen}
isChatOpen={isChatOpen}
themeMode={themeMode}
audioVisualizerType={audioVisualizerType}
audioVisualizerColor={audioVisualizerColor}
audioVisualizerColorShift={audioVisualizerColorShift}
Expand Down Expand Up @@ -262,10 +269,10 @@ export function AgentSessionView_01({
<AgentControlBar
variant="livekit"
controls={controls}
isChatOpen={chatOpen}
isChatOpen={isChatOpen}
isConnected={session.isConnected}
onDisconnect={session.end}
onIsChatOpenChange={setChatOpen}
onIsChatOpenChange={setIsChatOpen}
/>
</div>
</motion.div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const MotionAgentAudioVisualizerRadial = motion.create(AgentAudioVisualizerRadia
const MotionAgentAudioVisualizerWave = motion.create(AgentAudioVisualizerWave);

interface AudioVisualizerProps extends MotionProps {
themeMode?: 'dark' | 'light';
isChatOpen: boolean;
audioVisualizerType?: 'bar' | 'wave' | 'grid' | 'radial' | 'aura';
audioVisualizerColor?: `#${string}`;
Expand All @@ -32,6 +33,8 @@ interface AudioVisualizerProps extends MotionProps {
}

export function AudioVisualizer({
themeMode,
isChatOpen,
audioVisualizerType = 'bar',
audioVisualizerColor,
audioVisualizerColorShift = 0.3,
Expand All @@ -41,7 +44,6 @@ export function AudioVisualizer({
audioVisualizerGridRowCount = 15,
audioVisualizerGridColumnCount = 15,
audioVisualizerWaveLineWidth = 3,
isChatOpen,
className,
...props
}: AudioVisualizerProps) {
Expand All @@ -55,6 +57,7 @@ export function AudioVisualizer({
audioTrack={audioTrack}
color={audioVisualizerColor}
colorShift={audioVisualizerColorShift}
themeMode={themeMode}
className={cn('size-[300px] md:size-[450px]', className)}
{...props}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ export function useLocalTrackRef(source: Track.Source) {
}

interface TileLayoutProps {
chatOpen: boolean;
themeMode?: 'dark' | 'light';
isChatOpen: boolean;
audioVisualizerType?: 'bar' | 'wave' | 'grid' | 'radial' | 'aura';
audioVisualizerColor?: `#${string}`;
audioVisualizerColorShift?: number;
Expand All @@ -82,7 +83,8 @@ interface TileLayoutProps {
}

export function TileLayout({
chatOpen,
themeMode,
isChatOpen,
audioVisualizerType,
audioVisualizerColor,
audioVisualizerColorShift,
Expand All @@ -101,7 +103,7 @@ export function TileLayout({
const isScreenShareEnabled = screenShareTrack && !screenShareTrack.publication.isMuted;
const hasSecondTile = isCameraEnabled || isScreenShareEnabled;

const animationDelay = chatOpen ? 0 : 0.15;
const animationDelay = isChatOpen ? 0 : 0.15;
const isAvatar = agentVideoTrack !== undefined;
const videoWidth = agentVideoTrack?.publication.dimensions?.width ?? 0;
const videoHeight = agentVideoTrack?.publication.dimensions?.height ?? 0;
Expand All @@ -114,9 +116,9 @@ export function TileLayout({
<div
className={cn([
'grid',
!chatOpen && tileViewClassNames.agentChatClosed,
chatOpen && hasSecondTile && tileViewClassNames.agentChatOpenWithSecondTile,
chatOpen && !hasSecondTile && tileViewClassNames.agentChatOpenWithoutSecondTile,
!isChatOpen && tileViewClassNames.agentChatClosed,
isChatOpen && hasSecondTile && tileViewClassNames.agentChatOpenWithSecondTile,
isChatOpen && !hasSecondTile && tileViewClassNames.agentChatOpenWithoutSecondTile,
])}
>
<AnimatePresence mode="popLayout">
Expand All @@ -136,7 +138,7 @@ export function TileLayout({
<AudioVisualizer
key="audio-visualizer"
initial={{ scale: 1 }}
animate={{ scale: chatOpen ? 0.2 : 1 }}
animate={{ scale: isChatOpen ? 0.2 : 1 }}
transition={{
...ANIMATION_TRANSITION,
delay: animationDelay,
Expand All @@ -150,11 +152,12 @@ export function TileLayout({
audioVisualizerGridRowCount={audioVisualizerGridRowCount}
audioVisualizerGridColumnCount={audioVisualizerGridColumnCount}
audioVisualizerWaveLineWidth={audioVisualizerWaveLineWidth}
isChatOpen={chatOpen}
themeMode={themeMode}
isChatOpen={isChatOpen}
className={cn(
'absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2',
'bg-background rounded-[50px] border border-transparent transition-[border,drop-shadow]',
chatOpen && 'border-input shadow-2xl/10 delay-200',
isChatOpen && 'border-input shadow-2xl/10 delay-200',
)}
style={{ color: audioVisualizerColor }}
/>
Expand All @@ -177,7 +180,7 @@ export function TileLayout({
maskImage:
'radial-gradient(circle, rgba(0, 0, 0, 1) 0, rgba(0, 0, 0, 1) 500px, transparent 500px)',
filter: 'blur(0px)',
borderRadius: chatOpen ? 6 : 12,
borderRadius: isChatOpen ? 6 : 12,
}}
transition={{
...ANIMATION_TRANSITION,
Expand All @@ -191,14 +194,14 @@ export function TileLayout({
}}
className={cn(
'overflow-hidden bg-black drop-shadow-xl/80',
chatOpen ? 'h-[90px]' : 'h-auto w-full',
isChatOpen ? 'h-[90px]' : 'h-auto w-full',
)}
>
<VideoTrack
width={videoWidth}
height={videoHeight}
trackRef={agentVideoTrack}
className={cn(chatOpen && 'size-[90px] object-cover')}
className={cn(isChatOpen && 'size-[90px] object-cover')}
/>
</motion.div>
)}
Expand All @@ -208,8 +211,8 @@ export function TileLayout({
<div
className={cn([
'grid',
chatOpen && tileViewClassNames.secondTileChatOpen,
!chatOpen && tileViewClassNames.secondTileChatClosed,
isChatOpen && tileViewClassNames.secondTileChatOpen,
!isChatOpen && tileViewClassNames.secondTileChatClosed,
])}
>
{/* Camera & Screen Share */}
Expand Down
2 changes: 1 addition & 1 deletion packages/shadcn/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"type": "module",
"main": "index.ts",
"scripts": {
"registry:build": "rm -rf dist && shadcn build --output ./dist/r && pnpm registry:doc-gen",
"registry:build": "pnpm test && rm -rf dist && shadcn build --output ./dist/r && pnpm registry:doc-gen",
"registry:serve": "python3 -m http.server 3210 -d ./dist",
"registry:doc-gen": "node --experimental-strip-types --env-file=.env.local ./scripts/doc-gen.ts",
"registry:update": "pnpm registry:build && node --experimental-strip-types --env-file=.env.local ./scripts/update.ts",
Expand Down
24 changes: 24 additions & 0 deletions packages/shadcn/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,30 @@
],
"dependencies": ["@livekit/components-react@^2.0.0", "livekit-client@^2.0.0", "motion"],
"categories": ["agents", "blocks"]
},
{
"name": "all",
"type": "registry:item",
"title": "All",
"description": "Installs every component in the @agents-ui registry (excluding the nextjs-api-token-route).",
"files": [],
"registryDependencies": [
"@agents-ui/agent-disconnect-button",
"@agents-ui/agent-track-toggle",
"@agents-ui/agent-track-control",
"@agents-ui/agent-control-bar",
"@agents-ui/agent-audio-visualizer-bar",
"@agents-ui/agent-audio-visualizer-radial",
"@agents-ui/agent-audio-visualizer-grid",
"@agents-ui/agent-audio-visualizer-wave",
"@agents-ui/agent-audio-visualizer-aura",
"@agents-ui/agent-session-provider",
"@agents-ui/start-audio-button",
"@agents-ui/agent-chat-indicator",
"@agents-ui/agent-chat-transcript",
"@agents-ui/react-shader-toy",
"@agents-ui/agent-session-view-01"
]
}
]
}
Loading
Loading