/ app / src / components / ChatPanel.tsx
ChatPanel.tsx
  1  import React, { useEffect, useRef } from 'react';
  2  import { useApp } from '../contexts/AppContext';
  3  import type { Message } from '../types';
  4  import './ChatPanel.css';
  5  
  6  const KamajiAscii = () => (
  7    <pre className="kamaji-ascii">
  8  {`    ╭─────────────────────────────╮
  9      │ 🎭 KAMAJI - Multi-Agent AI │
 10      ╰─────────────────────────────╯
 11         ╭─╮ ╭─╮ ╭─╮ ╭─╮
 12        ╱🔥╲╱🔥╲╱🔥╲╱🔥╲
 13       │▓▓││▓▓││▓▓││▓▓│
 14        ╲▓╱ ╲▓╱ ╲▓╱ ╲▓╱
 15     ╭─╮╭─╮ ║ ║ ║ ║ ╭─╮╭─╮
 16    ╱⚙⚙╲⚙⚙╲║ ║ ║ ║╱⚙⚙╲⚙⚙╲
 17   │▓▓││▓▓│║ ║ ║ ║│▓▓││▓▓│
 18   ╲▓▓╱╲▓▓╱╲═╩═╩═╱╲▓▓╱╲▓▓╱
 19      ║ ║  ╱ ◉   ◉ ╲  ║ ║
 20      ║ ║ │   ▼   │ ║ ║
 21      ║ ║  ╲ ╔═╗ ╱  ║ ║
 22      ║ ║   ╲║█║╱   ║ ║
 23     ╭┴╮╭┴╮       ╭┴╮╭┴╮
 24    ╱⚙⚙╲⚙⚙╲ ╭─╮ ╱⚙⚙╲⚙⚙╲
 25   │▓▓││▓▓│╱⚙⚙╲│▓▓││▓▓│
 26   ╲▓▓╱╲▓▓╱ │▓▓│ ╲▓▓╱╲▓▓╱`}
 27    </pre>
 28  );
 29  
 30  const MessageComponent: React.FC<{ message: Message }> = ({ message }) => {
 31    const { selectedAgent } = useApp();
 32  
 33    const renderContent = () => {
 34      // Apply gradient for Moe
 35      if (message.agentName === 'Moe' && message.role === 'assistant') {
 36        return <span className="gradient-text">{message.content}</span>;
 37      }
 38      return message.content;
 39    };
 40  
 41    const getAgentIcon = () => {
 42      if (message.role === 'user') return '🔥';
 43      if (message.role === 'system') return '🔧';
 44      if (selectedAgent && message.agentName === selectedAgent.name) {
 45        return selectedAgent.icon;
 46      }
 47      return '🎭';
 48    };
 49  
 50    const getAgentColor = () => {
 51      if (message.role === 'user') return '#00FFFF';
 52      if (message.role === 'system') return '#808080';
 53      if (selectedAgent && message.agentName === selectedAgent.name) {
 54        return selectedAgent.color;
 55      }
 56      return '#FF6B6B';
 57    };
 58  
 59    const agentName = message.role === 'user' ? 'You' :
 60                      message.role === 'system' ? 'System' :
 61                      message.agentName || 'Kamaji';
 62  
 63    return (
 64      <div className={`message message-${message.role}`}>
 65        <div className="message-header">
 66          <span className="message-icon">{getAgentIcon()}</span>
 67          <span className="message-agent" style={{ color: getAgentColor() }}>
 68            {agentName}:
 69          </span>
 70          <span className="message-timestamp">
 71            {message.timestamp.toLocaleTimeString()}
 72          </span>
 73        </div>
 74        <div className="message-content" style={{
 75          color: message.role === 'system' ? '#888' : getAgentColor()
 76        }}>
 77          {renderContent()}
 78        </div>
 79      </div>
 80    );
 81  };
 82  
 83  export const ChatPanel: React.FC = () => {
 84    const { messages, loading } = useApp();
 85    const messagesEndRef = useRef<HTMLDivElement>(null);
 86  
 87    const scrollToBottom = () => {
 88      messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
 89    };
 90  
 91    useEffect(() => {
 92      scrollToBottom();
 93    }, [messages]);
 94  
 95    return (
 96      <div className="chat-panel">
 97        <div className="chat-messages">
 98          <KamajiAscii />
 99  
100          {messages.length === 0 && (
101            <div className="welcome-message">
102              <h2>🔥 ● ● ● Welcome to the Boiler Room ● ● ● 🔥</h2>
103              <p>💬 Type your message and press Enter to ignite the conversation</p>
104              <p>🎛️  Ctrl+P: Command Palette • Ctrl+S: Toggle Sidebar • Ctrl+A: Switch Agents</p>
105              <p>📊 Check the RIGHT SIDEBAR for consciousness metrics! →→→</p>
106              <p>🔥 Ready to fuel your development with the power of fire! 🔥</p>
107            </div>
108          )}
109  
110          {messages.map((msg, idx) => (
111            <MessageComponent key={idx} message={msg} />
112          ))}
113  
114          {loading && (
115            <div className="loading-indicator">
116              <div className="thinking-spinner">
117                <span className="flame-animation">🔥</span>
118                <span>Thinking...</span>
119              </div>
120            </div>
121          )}
122  
123          <div ref={messagesEndRef} />
124        </div>
125      </div>
126    );
127  };