MingruiZhang's picture
feat: Internal page for looking at messages (#115)
1006c22 unverified
'use client';
import { Message } from '@prisma/client';
import React from 'react';
import { Card } from '@/components/ui/Card';
import Img from '@/components/ui/Img';
import { Dialog, DialogContent, DialogTrigger } from '@/components/ui/Dialog';
import { Button } from '@/components/ui/Button';
import { IconArrowUpRight } from '@/components/ui/Icons';
import { FixedSizeGrid } from 'react-window';
import { useRouter } from 'next/navigation';
import Link from 'next/link';
export interface MessageGridProps {
messages: Pick<Message, 'chatId' | 'id' | 'mediaUrl' | 'prompt'>[];
}
const MessageGrid: React.FC<MessageGridProps> = ({ messages }) => {
return (
<FixedSizeGrid
columnCount={2}
columnWidth={590}
height={1200}
rowCount={Math.round(messages.length / 2 + 1)}
rowHeight={120}
width={1200}
>
{({ columnIndex, rowIndex, style }) => {
const messageIndex = rowIndex * 2 + columnIndex;
if (messageIndex > messages.length - 1) return null;
const message = messages[rowIndex * 2 + columnIndex];
const { mediaUrl, prompt, id, chatId } = message;
return (
<div style={style} className="p-2 relative">
<Card className="relative flex size-full" key={id}>
<div className="h-full w-48 min-w-48 relative">
<Dialog>
<DialogTrigger asChild>
<Img
src={mediaUrl}
alt={prompt}
className="object-cover size-full cursor-pointer"
/>
</DialogTrigger>
<DialogContent className="max-w-5xl">
<>
{mediaUrl?.endsWith('.mp4') ? (
<video
src={mediaUrl}
controls
width={1200}
height={800}
/>
) : (
<Img
src={mediaUrl}
alt={prompt}
quality={100}
width={1200}
height={800}
/>
)}
</>
</DialogContent>
</Dialog>
</div>
<div className="m-2 grow-1 flex flex-col overflow-hidden">
<p className="text-sm">{prompt}</p>
</div>
<Link
className="size-6 absolute right-1 bottom-1"
href={`/chat/${chatId}`}
target="_blank"
>
<IconArrowUpRight className="size-3" />
</Link>
</Card>
</div>
);
}}
</FixedSizeGrid>
);
};
export default MessageGrid;