Skip to content
Open
Changes from all commits
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
90 changes: 46 additions & 44 deletions apps/web/src/components/ChatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5416,50 +5416,52 @@ const MessagesTimeline = memo(function MessagesTimeline({
const canRevertAgentWork = revertTurnCountByUserMessageId.has(row.message.id);
return (
<div className="flex justify-end">
<div className="group relative max-w-[80%] rounded-2xl rounded-br-sm border border-border bg-secondary px-4 py-3">
{userImages.length > 0 && (
<div className="mb-2 grid max-w-[420px] grid-cols-2 gap-2">
{userImages.map(
(image: NonNullable<TimelineMessage["attachments"]>[number]) => (
<div
key={image.id}
className="overflow-hidden rounded-lg border border-border/80 bg-background/70"
>
{image.previewUrl ? (
<button
type="button"
className="h-full w-full cursor-zoom-in"
aria-label={`Preview ${image.name}`}
onClick={() => {
const preview = buildExpandedImagePreview(userImages, image.id);
if (!preview) return;
onImageExpand(preview);
}}
>
<img
src={image.previewUrl}
alt={image.name}
className="h-full max-h-[220px] w-full object-cover"
onLoad={onTimelineImageLoad}
onError={onTimelineImageLoad}
/>
</button>
) : (
<div className="flex min-h-[72px] items-center justify-center px-2 py-3 text-center text-[11px] text-muted-foreground/70">
{image.name}
</div>
)}
</div>
),
)}
</div>
)}
{row.message.text && (
<pre className="whitespace-pre-wrap wrap-break-word font-mono text-sm leading-relaxed text-foreground">
{row.message.text}
</pre>
)}
<div className="mt-1.5 flex items-center justify-end gap-2">
<div className="group flex max-w-[80%] flex-col items-end">
<div className="w-fit max-w-full rounded-2xl rounded-br-sm border border-border bg-secondary px-4 py-3">
{userImages.length > 0 && (
<div className="mb-2 grid max-w-[420px] grid-cols-2 gap-2">
{userImages.map(
(image: NonNullable<TimelineMessage["attachments"]>[number]) => (
<div
key={image.id}
className="overflow-hidden rounded-lg border border-border/80 bg-background/70"
>
{image.previewUrl ? (
<button
type="button"
className="h-full w-full cursor-zoom-in"
aria-label={`Preview ${image.name}`}
onClick={() => {
const preview = buildExpandedImagePreview(userImages, image.id);
if (!preview) return;
onImageExpand(preview);
}}
>
<img
src={image.previewUrl}
alt={image.name}
className="h-full max-h-[220px] w-full object-cover"
onLoad={onTimelineImageLoad}
onError={onTimelineImageLoad}
/>
</button>
) : (
<div className="flex min-h-[72px] items-center justify-center px-2 py-3 text-center text-[11px] text-muted-foreground/70">
{image.name}
</div>
)}
</div>
),
)}
</div>
)}
{row.message.text && (
<pre className="whitespace-pre-wrap wrap-break-word font-mono text-sm leading-relaxed text-foreground">
{row.message.text}
</pre>
)}
</div>
<div className="mt-1.5 flex items-center justify-end gap-2 pr-1">
<div className="flex items-center gap-1.5 opacity-0 transition-opacity duration-200 focus-within:opacity-100 group-hover:opacity-100">
{row.message.text && <MessageCopyButton text={row.message.text} />}
{canRevertAgentWork && (
Expand Down
Loading