@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
JavaScript
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]);
};