import React, { useEffect, useRef, useState } from 'react';
import ReactMarkdown, { Components } from 'react-markdown';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { nightOwl } from 'react-syntax-highlighter/dist/esm/styles/prism';
import remarkGfm from 'remark-gfm';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
import rehypeRaw from 'rehype-raw';
import SendIcon from '@mui/icons-material/Send';
import 'katex/dist/katex.min.css';
import { CopyButton } from './components/CopyButton';
// Define the code component props interface
interface CodeComponentProps {
node?: any;
inline?: boolean;
className?: string;
children?: React.ReactNode;
}
// Add types for math components
interface MathComponentProps {
value: string;
}
// Extend Components type to include math components
interface MarkdownComponents extends Components {
math?: (props: MathComponentProps) => JSX.Element;
inlineMath?: (props: MathComponentProps) => JSX.Element;
}
export type ChatMessage = {
id: string;
isSelf: boolean;
name: string;
message: string;
timestamp: number;
};
export type ChatTileProps = {
messages: ChatMessage[];
onSend: (message: string) => void;
isConnected?: boolean;
};
const MessageContent = ({ message }: { message: string }) => {
if (message.match(/^https?:\/\/.*\.(jpg|jpeg|png|gif|webp)$/i)) {
return (
);
}
const components: MarkdownComponents = {
code({ inline, className, children }: CodeComponentProps) {
const match = /language-(\w+)|^(\w+)/.exec(className || '');
const language = match ? match[1] || match[2] : '';
if (!inline && language) {
return (
{String(children)}
);
},
// Style links
a: ({ node, children, ...props }) => (
{children}
),
// Style tables
table: ({ node, ...props }) => (