diff options
Diffstat (limited to 'src/client/views/nodes/ChatBox/MessageComponent.tsx')
-rw-r--r-- | src/client/views/nodes/ChatBox/MessageComponent.tsx | 110 |
1 files changed, 38 insertions, 72 deletions
diff --git a/src/client/views/nodes/ChatBox/MessageComponent.tsx b/src/client/views/nodes/ChatBox/MessageComponent.tsx index fced0b4d5..f27a18891 100644 --- a/src/client/views/nodes/ChatBox/MessageComponent.tsx +++ b/src/client/views/nodes/ChatBox/MessageComponent.tsx @@ -1,11 +1,25 @@ +/* eslint-disable jsx-a11y/control-has-associated-label */ /* eslint-disable react/require-default-props */ -import React from 'react'; -import { observer } from 'mobx-react'; import { MathJax, MathJaxContext } from 'better-react-mathjax'; +import { observer } from 'mobx-react'; +import React from 'react'; +import * as Tb from 'react-icons/tb'; import ReactMarkdown from 'react-markdown'; -import { TbCircle0Filled, TbCircle1Filled, TbCircle2Filled, TbCircle3Filled, TbCircle4Filled, TbCircle5Filled, TbCircle6Filled, TbCircle7Filled, TbCircle8Filled, TbCircle9Filled } from 'react-icons/tb'; +import './MessageComponent.scss'; import { AssistantMessage } from './types'; +const TbCircles = [ + Tb.TbCircleNumber0Filled, + Tb.TbCircleNumber1Filled, + Tb.TbCircleNumber2Filled, + Tb.TbCircleNumber3Filled, + Tb.TbCircleNumber4Filled, + Tb.TbCircleNumber5Filled, + Tb.TbCircleNumber6Filled, + Tb.TbCircleNumber7Filled, + Tb.TbCircleNumber8Filled, + Tb.TbCircleNumber9Filled, +]; interface MessageComponentProps { message: AssistantMessage; toggleToolLogs: (index: number) => void; @@ -17,89 +31,41 @@ interface MessageComponentProps { isCurrent?: boolean; } -const MessageComponent: React.FC<MessageComponentProps> = function ({ message, toggleToolLogs, expandedLogIndex, goToLinkedDoc, index, showModal, setCurrentFile, isCurrent = false }) { - // const messageClass = `${message.role} ${isCurrent ? 'current-message' : ''}`; - - const LinkRenderer = ({ href, children }: { href: string; children: React.ReactNode }) => { - // console.log(href + " " + children) - const regex = /([a-zA-Z0-9_.!-]+)~~~(citation|file_path)/; - const matches = href.match(regex); - // console.log(href) - // console.log(matches) - const url = matches ? matches[1] : href; - const linkType = matches ? matches[2] : null; - if (linkType === 'citation') { - switch (children) { - case '0': - children = <TbCircle0Filled />; - break; - case '1': - children = <TbCircle1Filled />; - break; - case '2': - children = <TbCircle2Filled />; - break; - case '3': - children = <TbCircle3Filled />; - break; - case '4': - children = <TbCircle4Filled />; - break; - case '5': - children = <TbCircle5Filled />; - break; - case '6': - children = <TbCircle6Filled />; - break; - case '7': - children = <TbCircle7Filled />; - break; - case '8': - children = <TbCircle8Filled />; - break; - case '9': - children = <TbCircle9Filled />; - break; - default: - break; - } - } - // console.log(linkType) - const style = { - color: 'lightblue', - verticalAlign: linkType === 'citation' ? 'super' : 'baseline', - fontSize: linkType === 'citation' ? 'smaller' : 'inherit', - }; - - return ( - <a +const LinkRendererWrapper = (goToLinkedDoc: (url: string) => void, showModal: () => void, setCurrentFile: (file: { url: string }) => void) => + function LinkRenderer({ href, children }: { href?: string; children?: React.ReactNode }) { + const Children = TbCircles[Number(children)]; // pascal case variable needed to convert IconType to JSX.Element tag + const [, aurl, linkType] = href?.match(/([a-zA-Z0-9_.!-]+)~~~(citation|file_path)/) ?? [undefined, href, null]; + const renderType = (content: JSX.Element | null, click: (url: string) => void):JSX.Element => ( + // eslint-disable-next-line jsx-a11y/anchor-is-valid + <a className={`MessageComponent-${linkType}`} href="#" onClick={e => { e.preventDefault(); - if (linkType === 'citation') { - goToLinkedDoc(url); - } else if (linkType === 'file_path') { - showModal(); - setCurrentFile({ url }); - } - }} - style={style}> - {children} - </a> - ); + aurl && click(aurl); + }}> + {content} + </a> + ); // prettier-ignore + switch (linkType) { + case 'citation': return renderType(<Children />, (url: string) => goToLinkedDoc(url)); + case 'file_path': return renderType(null, (url: string) => { showModal(); setCurrentFile({ url }); }); + default: return null; + } // prettier-ignore }; +const MessageComponent: React.FC<MessageComponentProps> = function ({ message, toggleToolLogs, expandedLogIndex, goToLinkedDoc, index, showModal, setCurrentFile, isCurrent = false }) { + // const messageClass = `${message.role} ${isCurrent ? 'current-message' : ''}`; return ( <div className={`message ${message.role}`}> <MathJaxContext> <MathJax dynamic hideUntilTypeset="every"> - <ReactMarkdown components={{ a: LinkRenderer }}>{message.text ? message.text : ''}</ReactMarkdown> + <ReactMarkdown components={{ a: LinkRendererWrapper(goToLinkedDoc, showModal, setCurrentFile) }}>{message.text}</ReactMarkdown> </MathJax> </MathJaxContext> {message.image && <img src={message.image} alt="" />} <div className="message-footer"> {message.tool_logs && ( - <button className="toggle-logs-button" onClick={() => toggleToolLogs(index)}> + <button type="button" className="toggle-logs-button" onClick={() => toggleToolLogs(index)}> {expandedLogIndex === index ? 'Hide Code Interpreter Logs' : 'Show Code Interpreter Logs'} </button> )} |