import { Check, ChevronDown, ChevronUp, Copy, CornerUpLeft } from "lucide-react" import React, { useState } from "react" import ReactMarkdown from "react-markdown" import { Prism as SyntaxHighlighter } from "react-syntax-highlighter" import { vscDarkPlus } from "react-syntax-highlighter/dist/esm/styles/prism" import remarkGfm from "remark-gfm" import { Button } from "../../ui/button" import { copyToClipboard, stringifyContent } from "./lib/chatUtils" interface MessageProps { message: { role: "user" | "assistant" content: string context?: string } setContext: (context: string | null) => void setIsContextExpanded: (isExpanded: boolean) => void } export default function ChatMessage({ message, setContext, setIsContextExpanded, }: MessageProps) { const [expandedMessageIndex, setExpandedMessageIndex] = useState< number | null >(null) const [copiedText, setCopiedText] = useState(null) const renderCopyButton = (text: any) => ( ) const askAboutCode = (code: any) => { const contextString = stringifyContent(code) setContext(`Regarding this code:\n${contextString}`) setIsContextExpanded(false) } const renderMarkdownElement = (props: any) => { const { node, children } = props const content = stringifyContent(children) return (
{renderCopyButton(content)}
{React.createElement( node.tagName, { ...props, className: `${ props.className || "" } hover:bg-transparent rounded p-1 transition-colors`, }, children )}
) } return (
{message.role === "user" && (
{renderCopyButton(message.content)}
)} {message.context && (
setExpandedMessageIndex(expandedMessageIndex === 0 ? null : 0) } > Context {expandedMessageIndex === 0 ? ( ) : ( )}
{expandedMessageIndex === 0 && (
{renderCopyButton( message.context.replace(/^Regarding this code:\n/, "") )}
{(() => { const code = message.context.replace( /^Regarding this code:\n/, "" ) const match = /language-(\w+)/.exec(code) const language = match ? match[1] : "typescript" return (