"use client"; import { useRef, useState, useCallback } from "react"; import { SidebarTrigger } from "@multica/ui/components/ui/sidebar"; import { Badge } from "@multica/ui/components/ui/badge"; import { Button } from "@multica/ui/components/ui/button"; import { ChatInput } from "@multica/ui/components/chat-input"; import { MemoizedMarkdown } from "@multica/ui/components/markdown"; import { HugeiconsIcon } from "@hugeicons/react"; import { UserIcon, Copy01Icon, CheckmarkCircle02Icon } from "@hugeicons/core-free-icons"; import { toast } from "@multica/ui/components/ui/sonner"; import { useMessages } from "../hooks/use-messages"; import { useGateway } from "../hooks/use-gateway"; import { useHubStore } from "../hooks/use-hub-store"; import { useDeviceId } from "../hooks/use-device-id"; import { useScrollFade } from "../hooks/use-scroll-fade"; import { cn } from "@multica/ui/lib/utils"; const STATE_VARIANT: Record = { registered: "default", connected: "secondary", connecting: "secondary", disconnected: "destructive", } export function Chat() { const activeAgentId = useHubStore((s) => s.activeAgentId) const hub = useHubStore((s) => s.hub) const { messages, addUserMessage, addAssistantMessage } = useMessages() const { state: gwState, send } = useGateway({ onMessage: (msg) => { const payload = msg.payload as { agentId?: string; content?: string } if (payload?.agentId && payload?.content) { addAssistantMessage(payload.content, payload.agentId) } }, }) const handleSend = (text: string) => { if (!hub?.hubId || !activeAgentId) return addUserMessage(text, activeAgentId) send(hub.hubId, "message", { agentId: activeAgentId, content: text }) } const filtered = activeAgentId ? messages.filter(m => m.agentId === activeAgentId) : [] const canSend = gwState === "registered" && !!activeAgentId const deviceId = useDeviceId() const [deviceCopied, setDeviceCopied] = useState(false) const handleCopyDevice = useCallback(async () => { if (!deviceId) return await navigator.clipboard.writeText(deviceId) setDeviceCopied(true) toast.success("Device ID copied") setTimeout(() => setDeviceCopied(false), 2000) }, [deviceId]) const mainRef = useRef(null) const fadeStyle = useScrollFade(mainRef) return (
{deviceId && ( <> {deviceId} )} {gwState}
{!activeAgentId ? (
Select an agent to start chatting
) : filtered.length === 0 ? (
Send a message to start the conversation
) : (
{filtered.map((msg) => (
{msg.content}
))}
)}
); }