fix infinite rendering
This commit is contained in:
@@ -12,8 +12,12 @@ import { HomeView } from '@/views/HomeView'
|
|||||||
import { JobsView } from '@/views/JobsView'
|
import { JobsView } from '@/views/JobsView'
|
||||||
import { NotificationsView } from '@/views/NotificationsView'
|
import { NotificationsView } from '@/views/NotificationsView'
|
||||||
import { SettingsView } from '@/views/SettingsView'
|
import { SettingsView } from '@/views/SettingsView'
|
||||||
|
import { useSession } from '@livekit/components-react'
|
||||||
|
import { TokenSource } from 'livekit-client'
|
||||||
|
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
|
const session = useSession(TokenSource.sandboxTokenServer('your-sandbox-id'))
|
||||||
const [showSettings, setShowSettings] = useState(false)
|
const [showSettings, setShowSettings] = useState(false)
|
||||||
const [showJobs, setShowJobs] = useState(false)
|
const [showJobs, setShowJobs] = useState(false)
|
||||||
const [showNotifications, setShowNotifications] = useState(false)
|
const [showNotifications, setShowNotifications] = useState(false)
|
||||||
@@ -21,6 +25,7 @@ export function App() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HomeView
|
<HomeView
|
||||||
|
session={session}
|
||||||
onSettingsClick={() => setShowSettings(true)}
|
onSettingsClick={() => setShowSettings(true)}
|
||||||
onJobsClick={() => setShowJobs(true)}
|
onJobsClick={() => setShowJobs(true)}
|
||||||
onNotificationsClick={() => setShowNotifications(true)}
|
onNotificationsClick={() => setShowNotifications(true)}
|
||||||
|
|||||||
+16
-30
@@ -1,7 +1,6 @@
|
|||||||
import { useRef, useState, useEffect } from 'react'
|
import { useRef, useState, useEffect } from 'react'
|
||||||
import { useSession, useAgent, useChat, useSessionMessages } from '@livekit/components-react'
|
import { useAgent, useChat, useSessionMessages, type UseSessionReturn } from '@livekit/components-react'
|
||||||
import { Keyboard, Loader, SendHorizontal } from 'lucide-react'
|
import { Keyboard, Loader, SendHorizontal } from 'lucide-react'
|
||||||
import { TokenSource } from 'livekit-client'
|
|
||||||
|
|
||||||
import { AgentAudioVisualizerAura } from '@/components/agents-ui/agent-audio-visualizer-aura'
|
import { AgentAudioVisualizerAura } from '@/components/agents-ui/agent-audio-visualizer-aura'
|
||||||
import { AgentChatTranscript } from '@/components/agents-ui/agent-chat-transcript'
|
import { AgentChatTranscript } from '@/components/agents-ui/agent-chat-transcript'
|
||||||
@@ -10,34 +9,34 @@ import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerTrigger } from
|
|||||||
import { AppBar } from '@/components/AppBar'
|
import { AppBar } from '@/components/AppBar'
|
||||||
|
|
||||||
interface HomeViewProps {
|
interface HomeViewProps {
|
||||||
|
session: UseSessionReturn
|
||||||
onSettingsClick: () => void
|
onSettingsClick: () => void
|
||||||
onJobsClick: () => void
|
onJobsClick: () => void
|
||||||
onNotificationsClick: () => void
|
onNotificationsClick: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function HomeView({ onSettingsClick, onJobsClick, onNotificationsClick }: HomeViewProps) {
|
export function HomeView({ session, onSettingsClick, onJobsClick, onNotificationsClick }: HomeViewProps) {
|
||||||
const session = useSession(TokenSource.sandboxTokenServer('your-sandbox-id'))
|
|
||||||
const { microphoneTrack, state: agentState } = useAgent(session)
|
const { microphoneTrack, state: agentState } = useAgent(session)
|
||||||
const { messages } = useSessionMessages(session)
|
const { messages } = useSessionMessages(session)
|
||||||
const { send } = useChat({ room: session.room })
|
// const { send } = useChat({ room: session.room })
|
||||||
|
|
||||||
const [isOpen, setIsOpen] = useState(false)
|
const [isChatOpen, setChatOpen] = useState(false)
|
||||||
const [message, setMessage] = useState('')
|
const [message, setMessage] = useState('')
|
||||||
const [isSending, setIsSending] = useState(false)
|
const [isFormSubmitting, setFormSubmitting] = useState(false)
|
||||||
const inputRef = useRef<HTMLTextAreaElement>(null)
|
const inputRef = useRef<HTMLTextAreaElement>(null)
|
||||||
|
|
||||||
const isDisabled = isSending || message.trim().length === 0
|
const isDisabled = isFormSubmitting || message.trim().length === 0
|
||||||
|
|
||||||
const handleSend = async () => {
|
const handleSend = async () => {
|
||||||
if (isDisabled) return
|
if (isDisabled) return
|
||||||
try {
|
try {
|
||||||
setIsSending(true)
|
setFormSubmitting(true)
|
||||||
await send(message.trim())
|
await send(message.trim())
|
||||||
setMessage('')
|
setMessage('')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
} finally {
|
} finally {
|
||||||
setIsSending(false)
|
setFormSubmitting(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,19 +48,10 @@ export function HomeView({ onSettingsClick, onJobsClick, onNotificationsClick }:
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOpen && inputRef.current) {
|
if (isChatOpen && inputRef.current) {
|
||||||
inputRef.current.focus()
|
inputRef.current.focus()
|
||||||
}
|
}
|
||||||
}, [isOpen])
|
}, [isChatOpen])
|
||||||
|
|
||||||
// Auto-open when first message arrives
|
|
||||||
const hasAutoOpened = useRef(false)
|
|
||||||
useEffect(() => {
|
|
||||||
if (messages.length > 0 && !hasAutoOpened.current) {
|
|
||||||
hasAutoOpened.current = true
|
|
||||||
setIsOpen(true)
|
|
||||||
}
|
|
||||||
}, [messages.length])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-svh flex-col">
|
<div className="flex min-h-svh flex-col">
|
||||||
@@ -76,8 +66,7 @@ export function HomeView({ onSettingsClick, onJobsClick, onNotificationsClick }:
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Drawer open={isChatOpen} onOpenChange={setChatOpen}>
|
||||||
<Drawer open={isOpen} onOpenChange={setIsOpen}>
|
|
||||||
<DrawerTrigger asChild>
|
<DrawerTrigger asChild>
|
||||||
<Button variant="outline" size="lg" className="fixed bottom-4 left-1/2 z-50 size-12 -translate-x-1/2">
|
<Button variant="outline" size="lg" className="fixed bottom-4 left-1/2 z-50 size-12 -translate-x-1/2">
|
||||||
<Keyboard className="size-6" />
|
<Keyboard className="size-6" />
|
||||||
@@ -93,8 +82,6 @@ export function HomeView({ onSettingsClick, onJobsClick, onNotificationsClick }:
|
|||||||
<DrawerHeader>
|
<DrawerHeader>
|
||||||
<DrawerTitle>Chat</DrawerTitle>
|
<DrawerTitle>Chat</DrawerTitle>
|
||||||
</DrawerHeader>
|
</DrawerHeader>
|
||||||
|
|
||||||
{/* Messages area */}
|
|
||||||
<div className="flex-1 overflow-hidden">
|
<div className="flex-1 overflow-hidden">
|
||||||
{messages.length === 0 ? (
|
{messages.length === 0 ? (
|
||||||
<div className="flex h-full items-center justify-center text-sm text-muted-foreground">
|
<div className="flex h-full items-center justify-center text-sm text-muted-foreground">
|
||||||
@@ -104,14 +91,12 @@ export function HomeView({ onSettingsClick, onJobsClick, onNotificationsClick }:
|
|||||||
<AgentChatTranscript agentState={agentState} messages={messages} className="h-full" />
|
<AgentChatTranscript agentState={agentState} messages={messages} className="h-full" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Input area */}
|
|
||||||
<div className="border-t border-border p-4">
|
<div className="border-t border-border p-4">
|
||||||
<div className="flex items-end gap-2">
|
<div className="flex items-end gap-2">
|
||||||
<textarea
|
<textarea
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
value={message}
|
value={message}
|
||||||
disabled={isSending}
|
disabled={isFormSubmitting}
|
||||||
placeholder="Type a message..."
|
placeholder="Type a message..."
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
onChange={(e) => setMessage(e.target.value)}
|
onChange={(e) => setMessage(e.target.value)}
|
||||||
@@ -122,11 +107,11 @@ export function HomeView({ onSettingsClick, onJobsClick, onNotificationsClick }:
|
|||||||
type="button"
|
type="button"
|
||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
variant={isDisabled ? 'secondary' : 'default'}
|
variant={isDisabled ? 'secondary' : 'default'}
|
||||||
title={isSending ? 'Sending...' : 'Send'}
|
title={isFormSubmitting ? 'Sending...' : 'Send'}
|
||||||
onClick={handleSend}
|
onClick={handleSend}
|
||||||
className="shrink-0"
|
className="shrink-0"
|
||||||
>
|
>
|
||||||
{isSending ? <Loader className="animate-spin" /> : <SendHorizontal />}
|
{isFormSubmitting ? <Loader className="animate-spin" /> : <SendHorizontal />}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -136,3 +121,4 @@ export function HomeView({ onSettingsClick, onJobsClick, onNotificationsClick }:
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user