react-aiwriter
Version:
Typewriter effect inspired by ChatGPT ⌨️
117 lines • 5.97 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var react_1 = __importDefault(require("react"));
var useInterval_1 = __importDefault(require("./useInterval"));
var util_1 = require("./util");
var AIWriter = react_1.default.memo(function (_a) {
var children = _a.children, _b = _a.delay, delay = _b === void 0 ? 25 : _b, _c = _a.onEnd, onEnd = _c === void 0 ? function () { } : _c;
var _d = react_1.default.useState(0), pos = _d[0], setPos = _d[1];
var tokenLengths = react_1.default.useMemo(function () {
var arr = [];
var traverseNodesAndCountTokens = function (reactNode) {
var _a;
var nodeChildren = (_a = reactNode === null || reactNode === void 0 ? void 0 : reactNode.props) === null || _a === void 0 ? void 0 : _a.children;
if (Array.isArray(reactNode)) {
reactNode.forEach(function (node) {
if (typeof node === "object") {
traverseNodesAndCountTokens(node);
}
else if (typeof node === "string") {
// https://stackoverflow.com/questions/881085/count-the-number-of-occurrences-of-a-character-in-a-string-in-javascript
arr.push(node.split(" ").length);
}
});
}
if (nodeChildren === undefined) {
if (typeof reactNode === "string") {
arr.push(reactNode.split(" ").length);
}
}
// TODO mb try checking if it's a react element
if (typeof nodeChildren === "object") {
traverseNodesAndCountTokens(nodeChildren);
}
if (typeof nodeChildren === "string") {
arr.push(nodeChildren.split(" ").length);
}
return arr;
};
return traverseNodesAndCountTokens(children);
}, [children]);
var totalTokens = react_1.default.useMemo(function () { return tokenLengths.reduce(function (acc, curr) { return acc + curr; }, 0); }, [tokenLengths]);
var nodex = react_1.default.useMemo(function () {
var tmpCurrentLoopTokenPos = 0;
var tmpCurrentLoopNodePos = 0;
// inspired by https://impedans.me/web/searching-the-inner-text-content-of-nested-react-nodes/
var traverseNodesAndInjectAIWriter = function (reactNode) {
var _a;
if (tmpCurrentLoopTokenPos > pos) {
return null;
}
var nodeChildren = (_a = reactNode === null || reactNode === void 0 ? void 0 : reactNode.props) === null || _a === void 0 ? void 0 : _a.children;
if (Array.isArray(reactNode)) {
var joinedNodes_1 = [];
reactNode.forEach(function (node) {
if (typeof node === "object") {
joinedNodes_1.push(traverseNodesAndInjectAIWriter(node));
}
else if (typeof node === "string") {
tmpCurrentLoopTokenPos += node.split(" ").length;
tmpCurrentLoopNodePos++;
var _a = (0, util_1.getCurrentNodeOverflow)(tokenLengths, pos), nodeIndex = _a[0], currentNodePos = _a[1];
if (nodeIndex < tmpCurrentLoopNodePos) {
joinedNodes_1.push(node.slice(0, (0, util_1.getStringPosition)(node, " ", currentNodePos)));
}
joinedNodes_1.push(node);
}
});
return joinedNodes_1;
}
if (nodeChildren === undefined) {
if (typeof reactNode === "string") {
tmpCurrentLoopTokenPos += reactNode.split(" ").length;
tmpCurrentLoopNodePos++;
var _b = (0, util_1.getCurrentNodeOverflow)(tokenLengths, pos), nodeIndex = _b[0], currentNodePos = _b[1];
if (nodeIndex < tmpCurrentLoopNodePos) {
return reactNode.slice(0, (0, util_1.getStringPosition)(reactNode, " ", currentNodePos));
}
return reactNode;
}
}
// TODO mb try checking if it's a react element
if (typeof nodeChildren === "object") {
return react_1.default.createElement(reactNode.type, reactNode === null || reactNode === void 0 ? void 0 : reactNode.props, traverseNodesAndInjectAIWriter(nodeChildren));
}
if (typeof nodeChildren === "string") {
tmpCurrentLoopTokenPos += nodeChildren.split(" ").length;
tmpCurrentLoopNodePos++;
var _c = (0, util_1.getCurrentNodeOverflow)(tokenLengths, pos), nodeIndex = _c[0], currentNodePos = _c[1];
if (nodeIndex < tmpCurrentLoopNodePos) {
return react_1.default.createElement(reactNode.type, reactNode === null || reactNode === void 0 ? void 0 : reactNode.props, nodeChildren.slice(0, (0, util_1.getStringPosition)(nodeChildren, " ", currentNodePos)));
}
return reactNode;
}
};
return traverseNodesAndInjectAIWriter(children);
}, [children, pos, tokenLengths]);
(0, useInterval_1.default)(function () {
setPos(function (prevPos) {
if (prevPos + 1 >= totalTokens) {
onEnd();
}
return prevPos + 1;
});
}, totalTokens > pos ? delay : null);
// reset
react_1.default.useEffect(function () {
console.log("hmmm");
setPos(0);
}, [children]);
return nodex;
});
AIWriter.displayName = "AIWriter";
exports.default = AIWriter;
//# sourceMappingURL=AIWriter.js.map