sheer / src /pages /chat /components /HumanMessage.tsx
barreloflube's picture
refactor: improve chat page and manager with new features and optimizations
12621bc
raw
history blame
3.12 kB
import React from "react";
import { Button } from "@/components/ui/button";
import { X, Check, RefreshCcw, Pencil, ClipboardCopy } from "lucide-react";
import { AutosizeTextarea } from "@/components/ui/autosize-textarea";
import { toast } from "sonner";
import { MessageProps } from "../types";
import { DocumentBadgesScrollArea } from "./DocumentBadgesScrollArea";
interface HumanMessageComponentProps extends MessageProps {
onEdit?: () => void;
onRegenerate?: () => void;
isEditing?: boolean;
onSave?: (content: string) => void;
onCancelEdit?: () => void;
}
export const HumanMessageComponent = React.memo(({
message,
setPreviewDocument,
onEdit,
onRegenerate,
isEditing,
onSave,
onCancelEdit
}: HumanMessageComponentProps) => {
const [editedContent, setEditedContent] = React.useState(String(message.content));
if (message.response_metadata?.documents?.length) {
return (
<div className="flex flex-col gap-1 max-w-[70%] ml-auto items-end">
<DocumentBadgesScrollArea
documents={message.response_metadata.documents}
onPreview={(doc) => setPreviewDocument?.(doc)}
onRemove={() => {}}
removeable={false}
maxHeight="200px"
/>
</div>
);
}
return (
<div className="flex flex-col gap-1 max-w-[70%] ml-auto items-end group">
{isEditing ? (
<div className="flex flex-col gap-2 w-full">
<AutosizeTextarea
value={editedContent}
onChange={(e) => setEditedContent(e.target.value)}
className="bg-muted p-5 rounded-md"
maxHeight={300}
/>
<div className="flex gap-2 justify-end">
<Button
variant="ghost"
size="sm"
onClick={onCancelEdit}
>
<X className="h-4 w-4 mr-2" />
Cancel
</Button>
<Button
size="sm"
onClick={() => onSave?.(editedContent)}
>
<Check className="h-4 w-4 mr-2" />
Save
</Button>
</div>
</div>
) : (
<>
<div className="flex p-5 bg-muted rounded-md" style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>
{String(message.content)}
</div>
<div className="flex flex-row gap-1 opacity-0 group-hover:opacity-100">
<Button variant="ghost" size="icon" onClick={onRegenerate}>
<RefreshCcw className="h-4 w-4" />
</Button>
<Button variant="ghost" size="icon" onClick={onEdit}>
<Pencil className="h-4 w-4" />
</Button>
<Button
variant="ghost"
size="icon"
onClick={() => navigator.clipboard.writeText(String(message.content)).then(() => toast.success("Message copied to clipboard"))}
>
<ClipboardCopy className="h-4 w-4" />
</Button>
</div>
</>
)}
</div>
);
});
HumanMessageComponent.displayName = "HumanMessageComponent";