Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
101 changes: 86 additions & 15 deletions playground/src/components/MessageList.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import React, { useMemo, useRef, useEffect } from "react";
import React, { useMemo, useRef, useEffect, useState } from "react";
import MessageItem from "./MessageItem";
import RawMessageItem from "./RawMessageItem";
import { Message, User } from "../types";
import { toUIMessages } from "@convex-dev/agent/react";
import { Button } from "@/components/ui/button";
import { List, Layers } from "lucide-react";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";

interface MessageListProps {
users: User[];
Expand All @@ -17,6 +26,8 @@ const MessageList: React.FC<MessageListProps> = ({
onSelectMessage,
}) => {
const messagesEndRef = useRef<HTMLDivElement>(null);
const [viewMode, setViewMode] = useState<"raw" | "ui">("raw");

const uiMessages = useMemo(() => {
// TODO: segment the messages by "order" so the message item can show all of
// the messages that have been grouped together. Right now you can only see
Expand All @@ -41,20 +52,80 @@ const MessageList: React.FC<MessageListProps> = ({
}, [messages]); // Add messages as a dependency

return (
<div className="flex flex-col min-h-0 h-full overflow-y-auto">
{uiMessages.map((message) => (
<MessageItem
key={message._id}
user={users.find((user) => user._id === message.userId)}
message={message}
isSelected={message._id === selectedMessageId}
onClick={() => {
onSelectMessage(message._id);
}}
/>
))}
{/* Add an invisible div at the bottom to scroll to */}
<div ref={messagesEndRef} />
<div className="flex flex-col min-h-0 h-full">
{/* View mode toggle */}
<div className="flex items-center justify-between px-3 py-2 border-b bg-muted/30">
<span className="text-xs text-muted-foreground">
{viewMode === "raw"
? `${messages.length} messages (raw)`
: `${uiMessages.length} messages (grouped)`}
</span>
<TooltipProvider>
<div className="flex gap-1">
<Tooltip>
<TooltipTrigger asChild>
<Button
variant={viewMode === "raw" ? "default" : "ghost"}
size="sm"
className="h-7 px-2"
onClick={() => setViewMode("raw")}
>
<List size={14} className="mr-1" />
Raw
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Show all thread messages separately with full data</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant={viewMode === "ui" ? "default" : "ghost"}
size="sm"
className="h-7 px-2"
onClick={() => setViewMode("ui")}
>
<Layers size={14} className="mr-1" />
Grouped
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Show messages grouped as UIMessages (may hide some data)</p>
</TooltipContent>
</Tooltip>
</div>
</TooltipProvider>
</div>

{/* Messages list */}
<div className="flex-1 overflow-y-auto">
{viewMode === "raw"
? messages.map((message) => (
<RawMessageItem
key={message._id}
user={users.find((user) => user._id === message.userId)}
message={message}
isSelected={message._id === selectedMessageId}
onClick={() => {
onSelectMessage(message._id);
}}
/>
))
: uiMessages.map((message) => (
<MessageItem
key={message._id}
user={users.find((user) => user._id === message.userId)}
message={message}
isSelected={message._id === selectedMessageId}
onClick={() => {
onSelectMessage(message._id);
}}
/>
))}
{/* Add an invisible div at the bottom to scroll to */}
<div ref={messagesEndRef} />
</div>
</div>
);
};
Expand Down
Loading
Loading