Files
eve-alpha/src/components/ChatMessage.tsx
Aodhan Collins 66749a5ce7 Initial commit
2025-10-06 00:33:04 +01:00

82 lines
3.0 KiB
TypeScript

import { useState } from 'react'
import { User, Bot, Eye, EyeOff, Volume2 } from 'lucide-react'
import { ChatMessage as ChatMessageType } from '../stores/chatStore'
import { MessageContent } from './MessageContent'
import { TTSControls } from './TTSControls'
import { useSettingsStore } from '../stores/settingsStore'
import clsx from 'clsx'
interface ChatMessageProps {
message: ChatMessageType
}
export function ChatMessage({ message }: ChatMessageProps) {
const isUser = message.role === 'user'
const { ttsConversationMode } = useSettingsStore()
const [isTextVisible, setIsTextVisible] = useState(!ttsConversationMode)
return (
<div
className={clsx(
'flex gap-3 p-4 rounded-lg',
isUser
? 'bg-blue-50 dark:bg-blue-900/20 ml-8'
: 'bg-gray-50 dark:bg-gray-800/50 mr-8'
)}
>
<div
className={clsx(
'w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0',
isUser
? 'bg-blue-500 text-white'
: 'bg-gradient-to-br from-purple-500 to-indigo-600 text-white'
)}
>
{isUser ? <User className="w-5 h-5" /> : <Bot className="w-5 h-5" />}
</div>
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2 mb-1">
<span className="font-semibold text-gray-800 dark:text-white text-sm">
{isUser ? 'You' : 'EVE'}
</span>
<span className="text-xs text-gray-500 dark:text-gray-400">
{new Date(message.timestamp).toLocaleTimeString()}
</span>
</div>
<div className="text-gray-700 dark:text-gray-200">
{isUser ? (
// User messages: simple pre-wrap for plain text
<div className="whitespace-pre-wrap break-words">{message.content}</div>
) : (
// Assistant messages: full markdown rendering
<>
{ttsConversationMode && (
<div className="mb-2 flex items-center gap-2">
<button
onClick={() => setIsTextVisible(!isTextVisible)}
className="flex items-center gap-1 px-2 py-1 text-xs bg-purple-500/20 hover:bg-purple-500/30
text-purple-700 dark:text-purple-300 rounded-md transition-colors"
>
{isTextVisible ? <EyeOff className="w-3 h-3" /> : <Eye className="w-3 h-3" />}
{isTextVisible ? 'Hide Text' : 'Show Text'}
</button>
<div className="flex items-center gap-1 text-xs text-purple-600 dark:text-purple-400">
<Volume2 className="w-3 h-3" />
<span>Audio Mode</span>
</div>
</div>
)}
{isTextVisible && <MessageContent content={message.content} />}
<TTSControls
text={message.content}
messageId={message.id}
autoPlay={ttsConversationMode}
/>
</>
)}
</div>
</div>
</div>
)
}