UNPKG

remix-nlux

Version:

Remix IDE NLUX integration. Remix IDE is the leading IDE for building and deploying smart contracts on Ethereum. NLUX is a JavaScript and React library for building conversational AI experiences.

112 lines (97 loc) 4 kB
import {createChatItemDom} from '@shared/components/ChatItem/create'; import {ChatItemProps} from '@shared/components/ChatItem/props'; import {updateChatItemDom} from '@shared/components/ChatItem/update'; import {createMessageContent} from '@shared/components/Message/utils/createMessageContent'; import {createMarkdownStreamParser, MarkdownStreamParser} from '../../../../../../extra/markdown/src'; import {CompRenderer} from '../../../types/comp'; import {getElement} from '../../../utils/dom/getElement'; import {CompChatItemActions, CompChatItemElements, CompChatItemEvents, CompChatItemProps} from './chatItem.types'; export const renderChatItem: CompRenderer< CompChatItemProps, CompChatItemElements, CompChatItemEvents, CompChatItemActions > = ({ props, appendToRoot, compEvent, }) => { const root = createChatItemDom({ ...props.domProps, htmlSanitizer: props.htmlSanitizer, message: undefined, }); const messageContainer = getElement(root, '.nlux-comp-message'); if (!messageContainer) { throw new Error('Message container not found'); } const streamingRoot = document.createElement('div'); streamingRoot.classList.add('nlux-markdownStream-root'); const markdownContainer = document.createElement('div'); markdownContainer.classList.add('nlux-markdown-container'); markdownContainer.setAttribute('nlux-message-id', props.uid); streamingRoot.append(markdownContainer); messageContainer.append(streamingRoot); if (props.domProps.message) { const parsedMessage = createMessageContent( props.domProps.message ?? '', 'markdown', { markdownLinkTarget: props.markdownLinkTarget, syntaxHighlighter: props.syntaxHighlighter, htmlSanitizer: props.htmlSanitizer, }, ); markdownContainer.append(parsedMessage); } appendToRoot(root); let markdownStreamParser: MarkdownStreamParser | undefined = undefined; let markdownStreamProps: CompChatItemProps = {...props}; const initMarkdownStreamParser = (newProps: CompChatItemProps) => { return createMarkdownStreamParser(markdownContainer, { syntaxHighlighter: newProps.syntaxHighlighter, htmlSanitizer: newProps.htmlSanitizer, markdownLinkTarget: newProps.markdownLinkTarget, showCodeBlockCopyButton: newProps.showCodeBlockCopyButton, skipStreamingAnimation: newProps.skipStreamingAnimation, streamingAnimationSpeed: newProps.streamingAnimationSpeed, onComplete: () => compEvent('markdown-stream-complete'), }); }; return { elements: { chatItemContainer: root, }, actions: { focus: () => { root.focus(); }, processStreamedChunk: (chunk: string) => { if (!markdownStreamParser) { markdownStreamParser = initMarkdownStreamParser(markdownStreamProps); } markdownStreamParser.next(chunk); }, commitStreamedChunks: () => { if (markdownStreamParser) { markdownStreamParser.complete(); } }, updateMarkdownStreamRenderer: (newProps: Partial<CompChatItemProps>) => { markdownStreamProps = { ...markdownStreamProps, ...newProps, }; initMarkdownStreamParser(markdownStreamProps); }, updateDomProps: (oldProps: ChatItemProps, newProps: ChatItemProps) => { updateChatItemDom( root, oldProps, newProps, ); }, }, onDestroy: () => { root.remove(); markdownStreamParser = undefined; }, }; };