import { forwardRef, useState } from 'react'; import Avatar from '../Avatar'; import { FEEDBACK, MESSAGE_TYPE } from './conversationModels'; import Alert from './../assets/alert.svg'; import { ReactComponent as Like } from './../assets/like.svg'; import { ReactComponent as Dislike } from './../assets/dislike.svg'; import { ReactComponent as Copy } from './../assets/copy.svg'; import { ReactComponent as Checkmark } from './../assets/checkmark.svg'; import ReactMarkdown from 'react-markdown'; import copy from 'copy-to-clipboard'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism'; const DisableSourceFE = import.meta.env.VITE_DISABLE_SOURCE_FE || false; const ConversationBubble = forwardRef< HTMLDivElement, { message: string; type: MESSAGE_TYPE; className?: string; feedback?: FEEDBACK; handleFeedback?: (feedback: FEEDBACK) => void; sources?: { title: string; text: string }[]; } >(function ConversationBubble( { message, type, className, feedback, handleFeedback, sources }, ref, ) { const [showFeedback, setShowFeedback] = useState(false); const [openSource, setOpenSource] = useState(null); const [copied, setCopied] = useState(false); const handleCopyClick = (text: string) => { copy(text); setCopied(true); // Reset copied to false after a few seconds setTimeout(() => { setCopied(false); }, 2000); }; const List = ({ ordered, children, }: { ordered?: boolean; children: React.ReactNode; }) => { const Tag = ordered ? 'ol' : 'ul'; return {children}; }; let bubble; if (type === 'QUESTION') { bubble = (
{message}
); } else { bubble = (
setShowFeedback(true)} onMouseLeave={() => setShowFeedback(false)} >
{type === 'ERROR' && ( alert )} {String(children).replace(/\n$/, '')} ) : ( {children} ); }, ul({ node, children }) { return {children}; }, ol({ node, children }) { return {children}; }, }} > {message} {DisableSourceFE || type === 'ERROR' ? null : ( <>
Sources:
{sources?.map((source, index) => (
setOpenSource(openSource === index ? null : index) } >

{index + 1}. {source.title.substring(0, 45)}

))}
)}
{copied ? ( ) : ( { handleCopyClick(message); }} > )}
handleFeedback?.('LIKE')} >
handleFeedback?.('DISLIKE')} >
{sources && openSource !== null && sources[openSource] && (

Source: {sources[openSource].title}

{sources[openSource].text}

)}
); } return bubble; }); export default ConversationBubble;