"use client"; import { useEffect, useRef, useState } from "react"; import { GlassCard } from "@/components/glass/card"; import { renderMessageContent } from "@/lib/format"; import type { MessageRecord } from "@/lib/types"; import { cn } from "@/lib/utils"; import { useWebSocket } from "@/lib/ws/context"; interface LiveMessage { id: string; content: string; username: string; channelName?: string; timestamp: string; flagged?: boolean; metadata?: string | null; } export function LiveStream() { const [messages, setMessages] = useState([]); const scrollRef = useRef(null); const ws = useWebSocket(); useEffect(() => { const unsub = ws.on("message_created", (data: MessageRecord) => { // channel name lives inside the metadata JSON (channel.channelName) let channelName: string | undefined; try { const meta = typeof data.metadata === "string" ? JSON.parse(data.metadata) : data.metadata; channelName = meta?.channel?.channelName; } catch { channelName = undefined; } const msg: LiveMessage = { id: data.id, content: data.content || "(attachment)", username: data.username || "unknown", channelName, timestamp: new Date().toLocaleTimeString(), flagged: data.ai_status === "flagged" || data.ai_status === "warn", metadata: data.metadata ?? null, }; setMessages((prev) => [msg, ...prev].slice(0, 50)); }); return () => unsub(); }, [ws]); return (
Live Stream
{messages.length === 0 ? (
Waiting for messages...
) : ( messages.map((msg) => (
{msg.username} {renderMessageContent(msg.content, msg.metadata)} {msg.timestamp}
)) )}
); }