import styled from '@emotion/styled'; import ReactMarkdown from 'react-markdown'; import { Button, CopyButton, Loader } from '@mantine/core'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism'; import remarkGfm from 'remark-gfm'; import remarkMath from 'remark-math' import rehypeKatex from 'rehype-katex' import { Message } from "../types"; import { share } from '../utils'; import { ElevenLabsReaderButton } from '../elevenlabs'; // hide for everyone but screen readers const SROnly = styled.span` position: fixed; left: -9999px; top: -9999px; `; const Container = styled.div` &.by-user { } &.by-assistant { background: rgba(255, 255, 255, 0.02); } &.by-assistant + &.by-assistant, &.by-user + &.by-user { border-top: 0.2rem dotted rgba(0, 0, 0, 0.1); } position: relative; padding: 1.618rem; @media (max-width: 40em) { padding: 1rem; } .inner { margin: auto; } .content { font-family: "Open Sans", sans-serif; margin-top: 0rem; max-width: 100%; * { color: white; } p, ol, ul, li, h1, h2, h3, h4, h5, h6, img, blockquote, &>pre { max-width: 50rem; margin-left: auto; margin-right: auto; } img { display: block; max-width: 50rem; @media (max-width: 50rem) { max-width: 100%; } } ol { counter-reset: list-item; li { counter-increment: list-item; } } em, i { font-style: italic; } code { &, * { font-family: "Fira Code", monospace !important; } vertical-align: bottom; } /* Tables */ table { margin-top: 1.618rem; border-spacing: 0px; border-collapse: collapse; border: thin solid rgba(255, 255, 255, 0.1); width: 100%; max-width: 55rem; margin-left: auto; margin-right: auto; } td + td, th + th { border-left: thin solid rgba(255, 255, 255, 0.1); } tr { border-top: thin solid rgba(255, 255, 255, 0.1); } table td, table th { padding: 0.618rem 1rem; } th { font-weight: 600; background: rgba(255, 255, 255, 0.1); } } .metadata { display: flex; flex-wrap: wrap; align-items: center; font-family: "Work Sans", sans-serif; font-size: 0.8rem; font-weight: 400; opacity: 0.6; max-width: 50rem; margin-bottom: 0.0rem; margin-right: -0.5rem; margin-left: auto; margin-right: auto; span + span { margin-left: 1em; } .fa { font-size: 85%; } .fa + span { margin-left: 0.2em; } .mantine-Button-root { color: #ccc; font-size: 0.8rem; font-weight: 400; .mantine-Button-label { display: flex; align-items: center; } } } .fa { margin-right: 0.5em; font-size: 85%; } .buttons { text-align: right; } strong { font-weight: bold; } `; const EndOfChatMarker = styled.div` position: absolute; bottom: calc(-1.618rem - 0.5rem); left: 50%; width: 0.5rem; height: 0.5rem; margin-left: -0.25rem; border-radius: 50%; background: rgba(255, 255, 255, 0.1); `; function getRoleName(role: string, share = false) { switch (role) { case 'user': return !share ? 'You' : 'User'; case 'assistant': return 'ChatGPT'; case 'system': return 'System'; default: return role; } } function InlineLoader() { return ( ); } export default function MessageComponent(props: { message: Message, last: boolean, share?: boolean }) { if (props.message.role === 'system') { return null; } return {getRoleName(props.message.role, props.share)}: {props.message.role === 'assistant' && props.last && !props.message.done && } {props.message.done && } {({ copy, copied }) => ( {copied ? 'Copied' : 'Copy'} )} {typeof navigator.share !== 'undefined' && ( share(props.message.content)}> Share )} {({ copy, copied }) => ( {copied ? 'Copied' : 'Copy'} )} ) : ( {children} ) } }}>{props.message.content} {props.last && } }
{children}