File size: 3,968 Bytes
2accaeb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 type { ChatMessage } from '../types';
import { MarkdownRenderer } from './MarkdownRenderer';
import { UserIcon, DocumentTextIcon } from './icons';
// REELBOT_IMAGE_URL is not needed here anymore for the avatar itself

export const ChatMessageItem: React.FC<{ message: ChatMessage }> = React.memo(({ message }) => {
  const isUser = message.sender === 'user';

  const shouldDisplaySources = () => {
    if (message.sender === 'model' && message.groundingChunks && message.groundingChunks.length > 0) {
      const text = message.text.toLowerCase();
      return text.includes("sources:") || text.includes("source:") || text.includes("fuentes:") || text.includes("fuente:");
    }
    return false;
  };

  const isImageFile = message.file && message.file.dataUrl && message.file.type.startsWith('image/');
  const isDocumentFile = message.file && !isImageFile && (message.file.type.includes('pdf') || message.file.type.includes('word') || message.file.type.includes('document'));


  return (
    <div className={`flex ${isUser ? 'justify-end' : 'justify-start'} mb-4`}>
      <div
        className={`max-w-xl lg:max-w-2xl px-4 py-3 rounded-xl shadow ${
          isUser 
            ? 'bg-cyan-600 text-white rounded-br-none' 
            : 'bg-slate-700 text-slate-100 rounded-bl-none'
        }`}
      >
        <div className="flex items-center space-x-2 mb-1"> {/* Adjusted items-start to items-center for better emoji alignment */}
          {isUser ? (
            <UserIcon className="w-5 h-5 text-cyan-200 mt-0.5"/> 
          ) : (
            <span role="img" aria-label="ReelBot avatar" className="text-xl self-center">🤖</span>
          )}
          <span className="font-semibold text-sm self-center">{isUser ? 'Tú' : 'ReelBot'}</span>
        </div>

        {/* File Preview */}
        {message.file && (
          <div className="mb-2 p-2 border border-slate-500/50 rounded-md">
            {isImageFile ? (
              <img 
                src={message.file.dataUrl} 
                alt={message.file.name} 
                className="max-w-xs max-h-48 rounded object-contain" 
              />
            ) : isDocumentFile ? (
              <div className="flex items-center space-x-2">
                <DocumentTextIcon className="w-6 h-6 text-slate-400 flex-shrink-0" />
                <span className="text-xs text-slate-300 truncate" title={message.file.name}>
                  {message.file.name}
                </span>
              </div>
            ) : null }
          </div>
        )}
        
        {/* Message Text */}
        {message.text && (
          message.sender === 'model' ? (
            <MarkdownRenderer markdownText={message.text} />
          ) : (
            <p className="whitespace-pre-wrap break-words">{message.text}</p>
          )
        )}

        {message.error && <p className="text-red-300 text-xs mt-1">Error: {message.error}</p>}
        
        {shouldDisplaySources() && (
            <div className="mt-3 pt-2 border-t border-slate-600">
                <h4 className="text-xs font-semibold text-slate-400 mb-1">Sources:</h4>
                <ul className="list-disc list-inside space-y-1">
                    {message.groundingChunks!.map((chunk, index) => (
                        <li key={index} className="text-xs">
                            <a 
                                href={chunk.web.uri} 
                                target="_blank" 
                                rel="noopener noreferrer"
                                className="text-cyan-400 hover:text-cyan-300 hover:underline truncate block"
                                title={chunk.web.uri}
                            >
                                {chunk.web.title || chunk.web.uri}
                            </a>
                        </li>
                    ))}
                </ul>
            </div>
        )}
      </div>
    </div>
  );
});