UNPKG

@plteam/chat-ui

Version:

CUI Kit is a free and open-source library for creating AI assistant chat interfaces, built with React, Material UI, and TypeScript

74 lines (73 loc) 2.99 kB
import * as React from 'react'; import { ChatViewConstants } from '../../../ChatViewConstants'; import { chatClassNames } from '../../../core/chatClassNames'; class SmoothManager { ran = false; id = Math.ceil(Math.random() * 1000); delayValueMs = 40; _firstDelaySet = false; // Adding a small delay at the start to allow elements to render correctly firstDelayValueMs = 500; constructor() { } check = async () => { if (this.ran) return; this.ran = true; let delayMs = 0; const allMarkdownElements = document.getElementsByClassName(chatClassNames.messageAssistantRoot); const parent = allMarkdownElements.item(allMarkdownElements.length - 1); const elements = parent?.querySelectorAll(`.${chatClassNames.markdownSmoothedPending}`) ?? []; if (elements.length && !this._firstDelaySet) { this._firstDelaySet = true; delayMs += this.firstDelayValueMs; } elements.forEach((el) => { // TODO: Sort out the typing const hasAnimatedChildren = el.childNodes.values() .some((v) => ['li', 'ol', 'ul'].every(v => v !== el.tagName.toLowerCase()) && (v.classList?.contains(chatClassNames.markdownSmoothedAnimating) || v.classList?.contains(chatClassNames.markdownSmoothedPending))); el.classList.remove(chatClassNames.markdownSmoothedPending); if (hasAnimatedChildren) { /*console.log('has animated children', el, el.tagName); console.dir(el);*/ return; } el.style.animationDelay = `${delayMs}ms`; el.classList.add(chatClassNames.markdownSmoothedAnimating); // el.classList.add(`test-class-${key}`); delayMs += this.delayValueMs; }); delayMs -= this.delayValueMs; if (delayMs > 0) { await new Promise((resolve) => setTimeout(resolve, delayMs)); setTimeout(() => { elements?.forEach((el) => { el.classList.remove(chatClassNames.markdownSmoothedAnimating); el.style.animationDelay = '0s'; }); }, ChatViewConstants.TEXT_SMOOTH_ANIMATION_DURATION_MS); } this.ran = false; if (delayMs > 0) this.check(); }; /*checkThrottle = throttle( this.check, 50, { leading: true, trailing: true }, )*/ getStartTime = (delay) => { return performance.now() + delay; }; } const smoothManager = new SmoothManager(); export const useSmoothManager = (text, inProgress) => { /*const model = React.useMemo( () => inProgress ? new SmoothManager() : undefined, [inProgress] );*/ React.useEffect(() => { if (inProgress) smoothManager.check(); }, [text, inProgress]); };