import React, { useState } from "react";
import ReactMarkdown from 'react-markdown';
import './ChatWindow.css';
import FileListComponent from "./FileList";
import DiffViewer from "./DiffViewer";
// Individual message component for better modularity
const ChatMessage = ({ message }) => {
const [selectedFile, setSelectedFile] = useState(null);
const [isReasoningExpanded, setIsReasoningExpanded] = useState(false);
const toggleReasoning = () => {
setIsReasoningExpanded(!isReasoningExpanded);
};
// A simple handler to close the diff viewer
const handleCloseDiff = () => {
setSelectedFile(null);
};
const handleFileClick = (file) => {
setSelectedFile(file);
};
const messageClasses = `max-w-md p-4 rounded-lg shadow-md ${
message.isUser
? "bg-indigo-500 text-white ml-auto"
: "bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-gray-100 mr-auto"
}`;
return (
<div className={messageClasses}>
{message.reasoning && (
<div className="mb-2">
<button
onClick={toggleReasoning}
className="text-sm font-semibold text-indigo-700 hover:text-indigo-800 dark:text-gray-300 dark:hover:text-gray-100 focus:outline-none"
>
{isReasoningExpanded ? "Hide Reasoning ▲" : "Show Reasoning ▼"}
</button>
<div
className={`mt-2 text-xs transition-max-h duration-500 ease-in-out overflow-hidden ${
isReasoningExpanded ? "max-h-96" : "max-h-0"
}
text-gray-700 dark:text-gray-300`}
>
<ReactMarkdown>{message.reasoning}</ReactMarkdown>
</div>
</div>
)}
<ReactMarkdown>{message.text}</ReactMarkdown>
{message.code_diff && (
<FileListComponent files={message.code_diff} onFileClick={handleFileClick} />
)}
{selectedFile && <DiffViewer diff={selectedFile.diff} onClose={handleCloseDiff} />}
</div>
);
};
// Main ChatWindow component remains the same
const ChatWindow = ({ chatHistory }) => {
return (
<div className="space-y-4">
{chatHistory.map((message, index) => (
<div
key={index}
className={`flex ${
message.isUser ? "justify-end" : "justify-start"
}`}
>
<ChatMessage message={message} />
</div>
))}
</div>
);
};
export default ChatWindow;