Skip to content

Commit

Permalink
Merge pull request #9 from livekit-examples/jonas/dex-783-update-voic…
Browse files Browse the repository at this point in the history
…e-agent-design

Update agent design
  • Loading branch information
Ocupe authored Sep 30, 2024
2 parents 2118da4 + 4548b99 commit 83cd2ab
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 65 deletions.
17 changes: 17 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
--lk-va-bar-width: 72px;
--lk-control-bar-height: unset;
}

.agent-visualizer > .lk-audio-bar {
width: 72px;
}

.lk-agent-control-bar {
@apply border-t-0 p-0 h-min mr-4;
}

.lk-disconnect-button {
@apply h-[36px] hover:bg-[#6b221a] hover:text-[white] bg-[#31100c] border-[#6b221a];
}
9 changes: 8 additions & 1 deletion app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import "@livekit/components-styles";
import "./globals.css";
import { Public_Sans } from "next/font/google";

const publicSans400 = Public_Sans({
weight: "400",
subsets: ["latin"],
});

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en" className="h-full">
<html lang="en" className={`h-full ${publicSans400.className}`}>
<body className="h-full">{children}</body>
</html>
);
Expand Down
95 changes: 72 additions & 23 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
"use client";

import "@livekit/components-styles";

import { AnimatePresence, motion } from "framer-motion";
import {
LiveKitRoom,
useVoiceAssistant,
BarVisualizer,
RoomAudioRenderer,
VoiceAssistantControlBar,
AgentState,
DisconnectButton,
} from "@livekit/components-react";
import { useCallback, useState } from "react";
import { useCallback, useEffect, useState } from "react";
import { MediaDeviceFailure } from "livekit-client";
import type { ConnectionDetails } from "./api/connection-details/route";
import { NoAgentNotification } from "@/components/NoAgentNotification";
import { CloseIcon } from "@/components/CloseIcon";

export default function Page() {
const [connectionDetails, updateConnectionDetails] = useState<
ConnectionDetails | undefined
>(undefined);
const [agentState, setAgentState] = useState<AgentState>("disconnected");

const onConnectButtonClicked = useCallback(async () => {
const url = new URL(
Expand All @@ -31,7 +34,10 @@ export default function Page() {
}, []);

return (
<main data-lk-theme="default" className="h-full grid place-items-center">
<main
data-lk-theme="default"
className="h-full grid content-center bg-[var(--lk-bg)]"
>
<LiveKitRoom
token={connectionDetails?.participantToken}
serverUrl={connectionDetails?.serverUrl}
Expand All @@ -42,34 +48,77 @@ export default function Page() {
onDisconnected={() => {
updateConnectionDetails(undefined);
}}
className="grid items-center grid-rows-[1fr_min-content]"
className="grid grid-rows-[2fr_1fr] items-center"
>
{connectionDetails ? (
<SimpleVoiceAssistant />
) : (
<div className="flex w-full justify-center text-sm">
<button
className="lk-button uppercase"
onClick={() => onConnectButtonClicked()}
>
Start a conversation
</button>
</div>
)}
<VoiceAssistantControlBar />
<SimpleVoiceAssistant onStateChange={setAgentState} />
<ControlBar
onConnectButtonClicked={onConnectButtonClicked}
agentState={agentState}
/>
<RoomAudioRenderer />
<NoAgentNotification state={agentState} />
</LiveKitRoom>
</main>
);
}

function SimpleVoiceAssistant() {
function SimpleVoiceAssistant(props: {
onStateChange: (state: AgentState) => void;
}) {
const { state, audioTrack } = useVoiceAssistant();
useEffect(() => {
props.onStateChange(state);
}, [props, state]);
return (
<div className="h-[300px] max-w-[90vw] mx-auto">
<BarVisualizer
state={state}
barCount={5}
trackRef={audioTrack}
className="agent-visualizer"
options={{ minHeight: 24 }}
/>
</div>
);
}

function ControlBar(props: {
onConnectButtonClicked: () => void;
agentState: AgentState;
}) {
return (
<div className="h-80">
<BarVisualizer state={state} barCount={7} trackRef={audioTrack} />
<p className="text-center">{state}</p>
<NoAgentNotification state={state} />
<div className="relative h-[100px]">
<AnimatePresence>
{props.agentState === "disconnected" && (
<motion.button
initial={{ opacity: 0, top: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0, top: "-10px" }}
transition={{ duration: 1, ease: [0.09, 1.04, 0.245, 1.055] }}
className="uppercase absolute left-1/2 -translate-x-1/2 px-4 py-2 bg-white text-black rounded-md"
onClick={() => props.onConnectButtonClicked()}
>
Start a conversation
</motion.button>
)}
</AnimatePresence>
<AnimatePresence>
{props.agentState !== "disconnected" &&
props.agentState !== "connecting" && (
<motion.div
initial={{ opacity: 0, top: "10px" }}
animate={{ opacity: 1, top: 0 }}
exit={{ opacity: 0, top: "-10px" }}
transition={{ duration: 0.4, ease: [0.09, 1.04, 0.245, 1.055] }}
className="flex h-8 absolute left-1/2 -translate-x-1/2 justify-center"
>
<VoiceAssistantControlBar controls={{ leave: false }} />
<DisconnectButton>
<CloseIcon />
</DisconnectButton>
</motion.div>
)}
</AnimatePresence>
</div>
);
}
Expand Down
18 changes: 18 additions & 0 deletions components/CloseIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export function CloseIcon() {
return (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M3.33398 3.33334L12.6673 12.6667M12.6673 3.33334L3.33398 12.6667"
stroke="currentColor"
stroke-width="2"
stroke-linecap="square"
/>
</svg>
);
}
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
"lint": "next lint"
},
"dependencies": {
"@livekit/components-react": "^2.6.0",
"@livekit/components-styles": "^1.1.1",
"livekit-client": "^2.5.1",
"@livekit/components-react": "^2.6.1",
"@livekit/components-styles": "^1.1.3",
"framer-motion": "^11.9.0",
"livekit-client": "^2.5.5",
"livekit-server-sdk": "^2.6.1",
"next": "14.2.9",
"react": "^18",
Expand Down
Loading

0 comments on commit 83cd2ab

Please sign in to comment.