File size: 3,120 Bytes
12621bc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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";