funda-ui 4.5.777 → 4.5.888
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Chatbox/index.d.ts +12 -1
- package/Chatbox/index.js +226 -57
- package/lib/cjs/Chatbox/index.d.ts +12 -1
- package/lib/cjs/Chatbox/index.js +226 -57
- package/lib/esm/Chatbox/TypingEffect.tsx +61 -8
- package/lib/esm/Chatbox/index.tsx +137 -28
- package/lib/esm/Chatbox/utils/func.ts +18 -0
- package/lib/esm/Textarea/index.tsx +1 -1
- package/package.json +1 -1
package/lib/cjs/Chatbox/index.js
CHANGED
|
@@ -3212,10 +3212,10 @@ function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefine
|
|
|
3212
3212
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
3213
3213
|
|
|
3214
3214
|
var TypingEffect = function TypingEffect(_ref) {
|
|
3215
|
-
var
|
|
3216
|
-
content = _ref.content,
|
|
3215
|
+
var content = _ref.content,
|
|
3217
3216
|
speed = _ref.speed,
|
|
3218
|
-
onComplete = _ref.onComplete
|
|
3217
|
+
onComplete = _ref.onComplete,
|
|
3218
|
+
onUpdate = _ref.onUpdate;
|
|
3219
3219
|
var _useState = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useState)(''),
|
|
3220
3220
|
_useState2 = _slicedToArray(_useState, 2),
|
|
3221
3221
|
displayedContent = _useState2[0],
|
|
@@ -3224,25 +3224,82 @@ var TypingEffect = function TypingEffect(_ref) {
|
|
|
3224
3224
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
3225
3225
|
index = _useState4[0],
|
|
3226
3226
|
setIndex = _useState4[1];
|
|
3227
|
+
var _useState5 = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useState)([]),
|
|
3228
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
3229
|
+
imagePlaceholders = _useState6[0],
|
|
3230
|
+
setImagePlaceholders = _useState6[1];
|
|
3231
|
+
var _useState7 = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useState)(''),
|
|
3232
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
3233
|
+
processedContent = _useState8[0],
|
|
3234
|
+
setProcessedContent = _useState8[1];
|
|
3235
|
+
|
|
3236
|
+
// Extract and replace image tags
|
|
3237
|
+
(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function () {
|
|
3238
|
+
var extractImages = function extractImages(html) {
|
|
3239
|
+
var placeholders = [];
|
|
3240
|
+
var processedHtml = html;
|
|
3241
|
+
|
|
3242
|
+
// <img>
|
|
3243
|
+
processedHtml = processedHtml.replace(/<img[^>]*>/g, function (match) {
|
|
3244
|
+
var placeholder = "[IMG_".concat(placeholders.length, "]");
|
|
3245
|
+
placeholders.push({
|
|
3246
|
+
original: match,
|
|
3247
|
+
placeholder: placeholder,
|
|
3248
|
+
type: 'img'
|
|
3249
|
+
});
|
|
3250
|
+
return placeholder;
|
|
3251
|
+
});
|
|
3252
|
+
|
|
3253
|
+
// <svg>
|
|
3254
|
+
processedHtml = processedHtml.replace(/<svg[^>]*>[\s\S]*?<\/svg>/g, function (match) {
|
|
3255
|
+
var placeholder = "[SVG_".concat(placeholders.length, "]");
|
|
3256
|
+
placeholders.push({
|
|
3257
|
+
original: match,
|
|
3258
|
+
placeholder: placeholder,
|
|
3259
|
+
type: 'svg'
|
|
3260
|
+
});
|
|
3261
|
+
return placeholder;
|
|
3262
|
+
});
|
|
3263
|
+
return {
|
|
3264
|
+
processedHtml: processedHtml,
|
|
3265
|
+
placeholders: placeholders
|
|
3266
|
+
};
|
|
3267
|
+
};
|
|
3268
|
+
var _extractImages = extractImages(content),
|
|
3269
|
+
processedHtml = _extractImages.processedHtml,
|
|
3270
|
+
placeholders = _extractImages.placeholders;
|
|
3271
|
+
setProcessedContent(processedHtml);
|
|
3272
|
+
setImagePlaceholders(placeholders);
|
|
3273
|
+
}, [content]);
|
|
3274
|
+
|
|
3275
|
+
// Handle typing effects
|
|
3227
3276
|
(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function () {
|
|
3228
3277
|
var timer = setInterval(function () {
|
|
3229
|
-
if (index <
|
|
3230
|
-
|
|
3231
|
-
|
|
3278
|
+
if (index < processedContent.length) {
|
|
3279
|
+
var newContent = processedContent.substring(0, index + 1);
|
|
3280
|
+
|
|
3281
|
+
// Replace the completed placeholder
|
|
3282
|
+
imagePlaceholders.forEach(function (_ref2) {
|
|
3283
|
+
var original = _ref2.original,
|
|
3284
|
+
placeholder = _ref2.placeholder;
|
|
3285
|
+
if (newContent.includes(placeholder)) {
|
|
3286
|
+
newContent = newContent.replace(placeholder, original);
|
|
3287
|
+
}
|
|
3232
3288
|
});
|
|
3289
|
+
setDisplayedContent(newContent);
|
|
3233
3290
|
setIndex(function (prev) {
|
|
3234
3291
|
return prev + 1;
|
|
3235
3292
|
});
|
|
3236
|
-
|
|
3293
|
+
onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate();
|
|
3237
3294
|
} else {
|
|
3238
3295
|
clearInterval(timer);
|
|
3239
|
-
onComplete === null || onComplete === void 0 ? void 0 : onComplete();
|
|
3296
|
+
onComplete === null || onComplete === void 0 ? void 0 : onComplete();
|
|
3240
3297
|
}
|
|
3241
3298
|
}, speed);
|
|
3242
3299
|
return function () {
|
|
3243
3300
|
return clearInterval(timer);
|
|
3244
|
-
};
|
|
3245
|
-
}, [
|
|
3301
|
+
};
|
|
3302
|
+
}, [processedContent, index, speed, onComplete, onUpdate, imagePlaceholders]);
|
|
3246
3303
|
return /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("span", {
|
|
3247
3304
|
dangerouslySetInnerHTML: {
|
|
3248
3305
|
__html: displayedContent
|
|
@@ -3336,6 +3393,23 @@ function fixHtmlTags(html, withReasoning, reasoningSwitchLabel) {
|
|
|
3336
3393
|
// Replace with a valid label
|
|
3337
3394
|
return html.replace('<think>', "<details class=\"think\" ".concat(withReasoning ? 'open' : '', "><summary>").concat(reasoningSwitchLabel, "</summary><div class=\"think-content\">")).replace('</think>', '</div></details> ');
|
|
3338
3395
|
}
|
|
3396
|
+
function isStreamResponse(response) {
|
|
3397
|
+
// Method 1: Check Content-Type
|
|
3398
|
+
var contentType = response.headers.get('Content-Type');
|
|
3399
|
+
if (contentType) {
|
|
3400
|
+
return contentType.includes('text/event-stream') || contentType.includes('application/x-ndjson') || contentType.includes('application/stream+json');
|
|
3401
|
+
}
|
|
3402
|
+
|
|
3403
|
+
// Method 2: Check Transfer-Encoding
|
|
3404
|
+
var transferEncoding = response.headers.get('Transfer-Encoding');
|
|
3405
|
+
if (transferEncoding) {
|
|
3406
|
+
return transferEncoding.includes('chunked');
|
|
3407
|
+
}
|
|
3408
|
+
|
|
3409
|
+
// Method 3: Check if response.body is ReadableStream
|
|
3410
|
+
return response.body instanceof ReadableStream;
|
|
3411
|
+
}
|
|
3412
|
+
;
|
|
3339
3413
|
;// CONCATENATED MODULE: ./src/useStreamController.tsx
|
|
3340
3414
|
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
3341
3415
|
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, defineProperty = Object.defineProperty || function (obj, key, desc) { obj[key] = desc.value; }, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return defineProperty(generator, "_invoke", { value: makeInvokeMethod(innerFn, self, context) }), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; defineProperty(this, "_invoke", { value: function value(method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; } function maybeInvokeDelegate(delegate, context) { var methodName = context.method, method = delegate.iterator[methodName]; if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel; var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), defineProperty(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (val) { var object = Object(val), keys = []; for (var key in object) keys.push(key); return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; }
|
|
@@ -3809,6 +3883,11 @@ var Chatbox = function Chatbox(props) {
|
|
|
3809
3883
|
_useState14 = src_slicedToArray(_useState13, 2),
|
|
3810
3884
|
tempAnimText = _useState14[0],
|
|
3811
3885
|
setTempAnimText = _useState14[1];
|
|
3886
|
+
var _useState15 = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useState)(true),
|
|
3887
|
+
_useState16 = src_slicedToArray(_useState15, 2),
|
|
3888
|
+
enableStreamMode = _useState16[0],
|
|
3889
|
+
setEnableStreamMode = _useState16[1];
|
|
3890
|
+
var animatedMessagesRef = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(new Set()); // Add a ref to keep track of messages that have already been animated
|
|
3812
3891
|
|
|
3813
3892
|
//
|
|
3814
3893
|
var timer = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useRef)(null);
|
|
@@ -3851,6 +3930,12 @@ var Chatbox = function Chatbox(props) {
|
|
|
3851
3930
|
},
|
|
3852
3931
|
setContextData: function setContextData(v) {
|
|
3853
3932
|
contextDataRef.current = v;
|
|
3933
|
+
},
|
|
3934
|
+
getMessages: function getMessages() {
|
|
3935
|
+
return msgList;
|
|
3936
|
+
},
|
|
3937
|
+
setMessages: function setMessages(v) {
|
|
3938
|
+
setMsgList(v);
|
|
3854
3939
|
}
|
|
3855
3940
|
};
|
|
3856
3941
|
};
|
|
@@ -3887,6 +3972,7 @@ var Chatbox = function Chatbox(props) {
|
|
|
3887
3972
|
toolkitButtons = currentProps.toolkitButtons,
|
|
3888
3973
|
newChatButton = currentProps.newChatButton,
|
|
3889
3974
|
maxHistoryLength = currentProps.maxHistoryLength,
|
|
3975
|
+
customRequest = currentProps.customRequest,
|
|
3890
3976
|
renderParser = currentProps.renderParser,
|
|
3891
3977
|
requestBodyFormatter = currentProps.requestBodyFormatter,
|
|
3892
3978
|
nameFormatter = currentProps.nameFormatter,
|
|
@@ -3949,6 +4035,7 @@ var Chatbox = function Chatbox(props) {
|
|
|
3949
4035
|
maxHistoryLength: maxHistoryLength,
|
|
3950
4036
|
toolkitButtons: toolkitButtons,
|
|
3951
4037
|
newChatButton: newChatButton,
|
|
4038
|
+
customRequest: customRequest,
|
|
3952
4039
|
renderParser: renderParser,
|
|
3953
4040
|
requestBodyFormatter: requestBodyFormatter,
|
|
3954
4041
|
nameFormatter: nameFormatter,
|
|
@@ -3971,10 +4058,10 @@ var Chatbox = function Chatbox(props) {
|
|
|
3971
4058
|
//================================================================
|
|
3972
4059
|
// Custom buttons
|
|
3973
4060
|
//================================================================
|
|
3974
|
-
var
|
|
3975
|
-
|
|
3976
|
-
activeButtons =
|
|
3977
|
-
setActiveButtons =
|
|
4061
|
+
var _useState17 = (0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useState)({}),
|
|
4062
|
+
_useState18 = src_slicedToArray(_useState17, 2),
|
|
4063
|
+
activeButtons = _useState18[0],
|
|
4064
|
+
setActiveButtons = _useState18[1];
|
|
3978
4065
|
var executeButtonAction = function executeButtonAction(actionStr, buttonId, buttonElement) {
|
|
3979
4066
|
try {
|
|
3980
4067
|
// Create a new function to execute
|
|
@@ -4391,7 +4478,7 @@ var Chatbox = function Chatbox(props) {
|
|
|
4391
4478
|
return mainRequest(message);
|
|
4392
4479
|
case 20:
|
|
4393
4480
|
res = _context4.sent;
|
|
4394
|
-
if (
|
|
4481
|
+
if (res.useStreamRender) {
|
|
4395
4482
|
_context4.next = 32;
|
|
4396
4483
|
break;
|
|
4397
4484
|
}
|
|
@@ -4457,37 +4544,95 @@ var Chatbox = function Chatbox(props) {
|
|
|
4457
4544
|
};
|
|
4458
4545
|
var mainRequest = /*#__PURE__*/function () {
|
|
4459
4546
|
var _ref3 = src_asyncToGenerator( /*#__PURE__*/src_regeneratorRuntime().mark(function _callee5(msg) {
|
|
4460
|
-
var requestBodyRes, response, _errInfo, _args$responseExtract2, extractPath, _response, _errInfo2, jsonResponse, result, _iterator3, _step3, path,
|
|
4547
|
+
var currentStreamMode, requestBodyRes, customResponse, content, isStream, contentRes, response, _errInfo, _args$responseExtract2, extractPath, _response, _errInfo2, jsonResponse, result, _iterator3, _step3, path, _content2, _err;
|
|
4461
4548
|
return src_regeneratorRuntime().wrap(function _callee5$(_context5) {
|
|
4462
4549
|
while (1) switch (_context5.prev = _context5.next) {
|
|
4463
4550
|
case 0:
|
|
4464
|
-
|
|
4551
|
+
currentStreamMode = args().isStream; // Update stream mode
|
|
4552
|
+
setEnableStreamMode(currentStreamMode);
|
|
4553
|
+
_context5.prev = 2;
|
|
4465
4554
|
// Parse and interpolate request body template
|
|
4466
4555
|
requestBodyRes = JSON.parse((args().requestBodyTmpl || '{}').replace(/\{model\}/g, args().model).replace(/\{message\}/g, msg).replace(/\{token\}/g, chatId)); //
|
|
4467
4556
|
// If a formatter function exists, it is used to process the request body
|
|
4468
|
-
if (typeof args().requestBodyFormatter === 'function') {
|
|
4469
|
-
|
|
4557
|
+
if (!(typeof args().requestBodyFormatter === 'function')) {
|
|
4558
|
+
_context5.next = 8;
|
|
4559
|
+
break;
|
|
4470
4560
|
}
|
|
4471
|
-
|
|
4561
|
+
_context5.next = 7;
|
|
4562
|
+
return args().requestBodyFormatter(requestBodyRes, args().latestContextData, conversationHistory.current);
|
|
4563
|
+
case 7:
|
|
4564
|
+
requestBodyRes = _context5.sent;
|
|
4565
|
+
case 8:
|
|
4472
4566
|
// Scroll to the bottom
|
|
4473
4567
|
setTimeout(function () {
|
|
4474
4568
|
// Scroll to the bottom
|
|
4475
4569
|
scrollToBottom();
|
|
4476
4570
|
}, 500);
|
|
4477
|
-
if (!args().
|
|
4478
|
-
_context5.next =
|
|
4571
|
+
if (!(typeof args().customRequest === 'function')) {
|
|
4572
|
+
_context5.next = 25;
|
|
4479
4573
|
break;
|
|
4480
4574
|
}
|
|
4481
|
-
|
|
4575
|
+
// Update stream mode
|
|
4576
|
+
setEnableStreamMode(false);
|
|
4577
|
+
_context5.next = 13;
|
|
4578
|
+
return args().customRequest(msg, {
|
|
4579
|
+
requestBody: requestBodyRes,
|
|
4580
|
+
apiUrl: args().requestApiUrl || '',
|
|
4581
|
+
headers: args().headerConfigRes
|
|
4582
|
+
});
|
|
4583
|
+
case 13:
|
|
4584
|
+
customResponse = _context5.sent;
|
|
4585
|
+
content = customResponse.content, isStream = customResponse.isStream;
|
|
4586
|
+
contentRes = content; // Update stream mode
|
|
4587
|
+
setEnableStreamMode(isStream);
|
|
4588
|
+
|
|
4589
|
+
// NORMAL
|
|
4590
|
+
//++++++++++++++++++++++++++++++++++++++++++++++++
|
|
4591
|
+
if (!(!isStream && typeof contentRes === 'string' && contentRes.trim() !== '')) {
|
|
4592
|
+
_context5.next = 20;
|
|
4593
|
+
break;
|
|
4594
|
+
}
|
|
4595
|
+
// Replace with a valid label
|
|
4596
|
+
contentRes = fixHtmlTags(contentRes, args().withReasoning, args().reasoningSwitchLabel);
|
|
4597
|
+
return _context5.abrupt("return", {
|
|
4598
|
+
reply: formatLatestDisplayContent(contentRes),
|
|
4599
|
+
useStreamRender: false
|
|
4600
|
+
});
|
|
4601
|
+
case 20:
|
|
4602
|
+
if (!(isStream && isStreamResponse(contentRes))) {
|
|
4603
|
+
_context5.next = 24;
|
|
4604
|
+
break;
|
|
4605
|
+
}
|
|
4606
|
+
_context5.next = 23;
|
|
4607
|
+
return streamController.start(contentRes);
|
|
4608
|
+
case 23:
|
|
4609
|
+
return _context5.abrupt("return", {
|
|
4610
|
+
reply: tempAnimText,
|
|
4611
|
+
// The final content will be in tempAnimText
|
|
4612
|
+
useStreamRender: true
|
|
4613
|
+
});
|
|
4614
|
+
case 24:
|
|
4615
|
+
// DEFAULT
|
|
4616
|
+
//++++++++++++++++++++++++++++++++++++++++++++++++
|
|
4617
|
+
if (contentRes === null) {
|
|
4618
|
+
// Update stream mode
|
|
4619
|
+
setEnableStreamMode(currentStreamMode);
|
|
4620
|
+
}
|
|
4621
|
+
case 25:
|
|
4622
|
+
if (!currentStreamMode) {
|
|
4623
|
+
_context5.next = 39;
|
|
4624
|
+
break;
|
|
4625
|
+
}
|
|
4626
|
+
_context5.next = 28;
|
|
4482
4627
|
return fetch(args().requestApiUrl || '', {
|
|
4483
4628
|
method: "POST",
|
|
4484
4629
|
body: JSON.stringify(requestBodyRes),
|
|
4485
4630
|
headers: args().headerConfigRes
|
|
4486
4631
|
});
|
|
4487
|
-
case
|
|
4632
|
+
case 28:
|
|
4488
4633
|
response = _context5.sent;
|
|
4489
4634
|
if (response.ok) {
|
|
4490
|
-
_context5.next =
|
|
4635
|
+
_context5.next = 34;
|
|
4491
4636
|
break;
|
|
4492
4637
|
}
|
|
4493
4638
|
_errInfo = "[ERROR] HTTP Error ".concat(response.status, ": ").concat(response.statusText);
|
|
@@ -4496,40 +4641,44 @@ var Chatbox = function Chatbox(props) {
|
|
|
4496
4641
|
// hide loader
|
|
4497
4642
|
setLoaderDisplay(false);
|
|
4498
4643
|
return _context5.abrupt("return", {
|
|
4499
|
-
reply: _errInfo
|
|
4644
|
+
reply: _errInfo,
|
|
4645
|
+
useStreamRender: false
|
|
4500
4646
|
});
|
|
4501
|
-
case
|
|
4502
|
-
_context5.next =
|
|
4647
|
+
case 34:
|
|
4648
|
+
_context5.next = 36;
|
|
4503
4649
|
return streamController.start(response);
|
|
4504
|
-
case
|
|
4650
|
+
case 36:
|
|
4505
4651
|
return _context5.abrupt("return", {
|
|
4506
|
-
reply: tempAnimText
|
|
4652
|
+
reply: tempAnimText,
|
|
4653
|
+
// The final content will be in tempAnimText
|
|
4654
|
+
useStreamRender: true
|
|
4507
4655
|
});
|
|
4508
|
-
case
|
|
4656
|
+
case 39:
|
|
4509
4657
|
// Extract response using the path
|
|
4510
4658
|
extractPath = (_args$responseExtract2 = args().responseExtractPath) === null || _args$responseExtract2 === void 0 ? void 0 : _args$responseExtract2.slice(1);
|
|
4511
|
-
_context5.next =
|
|
4659
|
+
_context5.next = 42;
|
|
4512
4660
|
return fetch(args().requestApiUrl || '', {
|
|
4513
4661
|
method: "POST",
|
|
4514
4662
|
headers: args().headerConfigRes,
|
|
4515
4663
|
body: JSON.stringify(requestBodyRes),
|
|
4516
4664
|
signal: abortController.current.signal
|
|
4517
4665
|
});
|
|
4518
|
-
case
|
|
4666
|
+
case 42:
|
|
4519
4667
|
_response = _context5.sent;
|
|
4520
4668
|
if (_response.ok) {
|
|
4521
|
-
_context5.next =
|
|
4669
|
+
_context5.next = 47;
|
|
4522
4670
|
break;
|
|
4523
4671
|
}
|
|
4524
4672
|
_errInfo2 = "[ERROR] HTTP Error ".concat(_response.status, ": ").concat(_response.statusText); // hide loader
|
|
4525
4673
|
setLoaderDisplay(false);
|
|
4526
4674
|
return _context5.abrupt("return", {
|
|
4527
|
-
reply: _errInfo2
|
|
4675
|
+
reply: _errInfo2,
|
|
4676
|
+
useStreamRender: false
|
|
4528
4677
|
});
|
|
4529
|
-
case
|
|
4530
|
-
_context5.next =
|
|
4678
|
+
case 47:
|
|
4679
|
+
_context5.next = 49;
|
|
4531
4680
|
return _response.json();
|
|
4532
|
-
case
|
|
4681
|
+
case 49:
|
|
4533
4682
|
jsonResponse = _context5.sent;
|
|
4534
4683
|
// hide loader
|
|
4535
4684
|
setLoaderDisplay(false);
|
|
@@ -4547,30 +4696,32 @@ var Chatbox = function Chatbox(props) {
|
|
|
4547
4696
|
_iterator3.f();
|
|
4548
4697
|
}
|
|
4549
4698
|
}
|
|
4550
|
-
|
|
4551
|
-
|
|
4699
|
+
_content2 = result; // Replace with a valid label
|
|
4700
|
+
_content2 = fixHtmlTags(_content2, args().withReasoning, args().reasoningSwitchLabel);
|
|
4552
4701
|
return _context5.abrupt("return", {
|
|
4553
|
-
reply: formatLatestDisplayContent(
|
|
4702
|
+
reply: formatLatestDisplayContent(_content2),
|
|
4703
|
+
useStreamRender: false
|
|
4554
4704
|
});
|
|
4555
|
-
case
|
|
4556
|
-
_context5.next =
|
|
4705
|
+
case 56:
|
|
4706
|
+
_context5.next = 64;
|
|
4557
4707
|
break;
|
|
4558
|
-
case
|
|
4559
|
-
_context5.prev =
|
|
4560
|
-
_context5.t0 = _context5["catch"](
|
|
4708
|
+
case 58:
|
|
4709
|
+
_context5.prev = 58;
|
|
4710
|
+
_context5.t0 = _context5["catch"](2);
|
|
4561
4711
|
_err = "--> Error in mainRequest: ".concat(_context5.t0);
|
|
4562
4712
|
console.error(_err);
|
|
4563
4713
|
|
|
4564
4714
|
//reset SSE
|
|
4565
4715
|
closeSSE();
|
|
4566
4716
|
return _context5.abrupt("return", {
|
|
4567
|
-
reply: _err
|
|
4717
|
+
reply: _err,
|
|
4718
|
+
useStreamRender: false
|
|
4568
4719
|
});
|
|
4569
|
-
case
|
|
4720
|
+
case 64:
|
|
4570
4721
|
case "end":
|
|
4571
4722
|
return _context5.stop();
|
|
4572
4723
|
}
|
|
4573
|
-
}, _callee5, null, [[
|
|
4724
|
+
}, _callee5, null, [[2, 58]]);
|
|
4574
4725
|
}));
|
|
4575
4726
|
return function mainRequest(_x8) {
|
|
4576
4727
|
return _ref3.apply(this, arguments);
|
|
@@ -4580,7 +4731,7 @@ var Chatbox = function Chatbox(props) {
|
|
|
4580
4731
|
// exposes the following methods
|
|
4581
4732
|
(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useImperativeHandle)(propsRef.current.contentRef, function () {
|
|
4582
4733
|
return exposedMethods();
|
|
4583
|
-
}, [propsRef.current.contentRef, inputContentRef, msInput]);
|
|
4734
|
+
}, [propsRef.current.contentRef, inputContentRef, msInput, msgList]);
|
|
4584
4735
|
|
|
4585
4736
|
// Update ref when props change
|
|
4586
4737
|
(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function () {
|
|
@@ -4600,6 +4751,12 @@ var Chatbox = function Chatbox(props) {
|
|
|
4600
4751
|
setMsgList(props.defaultMessages);
|
|
4601
4752
|
}
|
|
4602
4753
|
}, [props.defaultMessages]);
|
|
4754
|
+
(0,external_root_React_commonjs2_react_commonjs_react_amd_react_.useEffect)(function () {
|
|
4755
|
+
if (Array.isArray(props.defaultMessages) && props.defaultMessages.length > 0) {
|
|
4756
|
+
// Update the default messages
|
|
4757
|
+
setMsgList(props.defaultMessages);
|
|
4758
|
+
}
|
|
4759
|
+
}, [props.defaultMessages]);
|
|
4603
4760
|
return /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement((external_root_React_commonjs2_react_commonjs_react_amd_react_default()).Fragment, null, /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement((dist_cjs_default()), {
|
|
4604
4761
|
show: true,
|
|
4605
4762
|
containerClassName: "Chatbox"
|
|
@@ -4672,6 +4829,10 @@ var Chatbox = function Chatbox(props) {
|
|
|
4672
4829
|
}, msgList.map(function (msg, index) {
|
|
4673
4830
|
var _msg$tag;
|
|
4674
4831
|
var isAnimProgress = tempAnimText !== '' && msg.sender !== args().questionNameRes && index === msgList.length - 1 && loading;
|
|
4832
|
+
var hasAnimated = animatedMessagesRef.current.has(index);
|
|
4833
|
+
|
|
4834
|
+
// Mark the message as animated;
|
|
4835
|
+
animatedMessagesRef.current.add(index);
|
|
4675
4836
|
return /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("div", {
|
|
4676
4837
|
key: index,
|
|
4677
4838
|
className: ((_msg$tag = msg.tag) === null || _msg$tag === void 0 ? void 0 : _msg$tag.indexOf('[reply]')) < 0 ? 'request' : 'reply',
|
|
@@ -4688,19 +4849,25 @@ var Chatbox = function Chatbox(props) {
|
|
|
4688
4849
|
dangerouslySetInnerHTML: {
|
|
4689
4850
|
__html: "".concat(msg.content, " <span class=\"qa-timestamp\">").concat(msg.timestamp, "</span>")
|
|
4690
4851
|
}
|
|
4691
|
-
})) : /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement((external_root_React_commonjs2_react_commonjs_react_amd_react_default()).Fragment, null,
|
|
4852
|
+
})) : /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement((external_root_React_commonjs2_react_commonjs_react_amd_react_default()).Fragment, null, enableStreamMode ? /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement((external_root_React_commonjs2_react_commonjs_react_amd_react_default()).Fragment, null, /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("div", {
|
|
4692
4853
|
className: "qa-content",
|
|
4693
4854
|
dangerouslySetInnerHTML: {
|
|
4694
4855
|
__html: "".concat(msg.content, " <span class=\"qa-timestamp\">").concat(msg.timestamp, "</span>")
|
|
4695
4856
|
}
|
|
4696
4857
|
})) : /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement((external_root_React_commonjs2_react_commonjs_react_amd_react_default()).Fragment, null, /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("div", {
|
|
4697
4858
|
className: "qa-content"
|
|
4698
|
-
}, /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement(
|
|
4699
|
-
|
|
4859
|
+
}, hasAnimated ? /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("div", {
|
|
4860
|
+
dangerouslySetInnerHTML: {
|
|
4861
|
+
__html: "".concat(msg.content, " <span class=\"qa-timestamp\">").concat(msg.timestamp, "</span>")
|
|
4862
|
+
}
|
|
4863
|
+
}) : /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement(src_TypingEffect, {
|
|
4864
|
+
onUpdate: function onUpdate() {
|
|
4865
|
+
scrollToBottom();
|
|
4866
|
+
},
|
|
4700
4867
|
content: "".concat(msg.content, " <span class=\"qa-timestamp\">").concat(msg.timestamp, "</span>"),
|
|
4701
4868
|
speed: 10
|
|
4702
4869
|
})))));
|
|
4703
|
-
}),
|
|
4870
|
+
}), enableStreamMode ? /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement((external_root_React_commonjs2_react_commonjs_react_amd_react_default()).Fragment, null, args().verbose ? /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement((external_root_React_commonjs2_react_commonjs_react_amd_react_default()).Fragment, null, tempAnimText !== '' && loading ? /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement((external_root_React_commonjs2_react_commonjs_react_amd_react_default()).Fragment, null, /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("div", {
|
|
4704
4871
|
className: "reply reply-waiting"
|
|
4705
4872
|
}, /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("div", {
|
|
4706
4873
|
className: "qa-name"
|
|
@@ -4742,7 +4909,7 @@ var Chatbox = function Chatbox(props) {
|
|
|
4742
4909
|
dangerouslySetInnerHTML: {
|
|
4743
4910
|
__html: "".concat(tempAnimText)
|
|
4744
4911
|
}
|
|
4745
|
-
}))) : null)) : null)) : null, !
|
|
4912
|
+
}))) : null)) : null)) : null, !enableStreamMode ? /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement((external_root_React_commonjs2_react_commonjs_react_amd_react_default()).Fragment, null, loading ? /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement((external_root_React_commonjs2_react_commonjs_react_amd_react_default()).Fragment, null, /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("div", {
|
|
4746
4913
|
className: "reply reply-waiting"
|
|
4747
4914
|
}, /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("div", {
|
|
4748
4915
|
className: "qa-name"
|
|
@@ -4766,6 +4933,7 @@ var Chatbox = function Chatbox(props) {
|
|
|
4766
4933
|
}))) : null)) : null) : null, args().newChatButton && msgList.length > 0 && /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("div", {
|
|
4767
4934
|
className: "newchat-btn"
|
|
4768
4935
|
}, /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("button", {
|
|
4936
|
+
id: "".concat(args().prefix || 'custom-', "chatbox-btn-new-").concat(chatId),
|
|
4769
4937
|
onClick: function onClick(e) {
|
|
4770
4938
|
return executeButtonAction(args().newChatButton.onClick, "".concat(args().prefix || 'custom-', "chatbox-btn-new-").concat(chatId), e.currentTarget);
|
|
4771
4939
|
}
|
|
@@ -4799,7 +4967,7 @@ var Chatbox = function Chatbox(props) {
|
|
|
4799
4967
|
onClick: function onClick(e) {
|
|
4800
4968
|
e.preventDefault();
|
|
4801
4969
|
e.stopPropagation();
|
|
4802
|
-
if (!
|
|
4970
|
+
if (!enableStreamMode) {
|
|
4803
4971
|
// normal request
|
|
4804
4972
|
abortNormalRequest();
|
|
4805
4973
|
} else {
|
|
@@ -4820,7 +4988,7 @@ var Chatbox = function Chatbox(props) {
|
|
|
4820
4988
|
e.stopPropagation();
|
|
4821
4989
|
|
|
4822
4990
|
// normal request
|
|
4823
|
-
if (!
|
|
4991
|
+
if (!enableStreamMode) {
|
|
4824
4992
|
if (abortController.current.signal.aborted) {
|
|
4825
4993
|
reconnectNormalRequest();
|
|
4826
4994
|
}
|
|
@@ -4846,6 +5014,7 @@ var Chatbox = function Chatbox(props) {
|
|
|
4846
5014
|
var isActive = activeButtons[_id];
|
|
4847
5015
|
return /*#__PURE__*/external_root_React_commonjs2_react_commonjs_react_amd_react_default().createElement("button", {
|
|
4848
5016
|
key: index,
|
|
5017
|
+
id: _id,
|
|
4849
5018
|
className: "".concat(btn.value || '', " ").concat(isActive ? 'active' : ''),
|
|
4850
5019
|
onClick: function onClick(e) {
|
|
4851
5020
|
return executeButtonAction(btn.onClick, _id, e.currentTarget);
|
|
@@ -1,30 +1,83 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
interface TypingEffectProps {
|
|
4
|
-
messagesDiv: any;
|
|
5
4
|
content: string; // The content to display
|
|
6
5
|
speed: number; // Speed of typing in milliseconds
|
|
7
6
|
onComplete?: () => void; // Callback when typing is complete
|
|
7
|
+
onUpdate?: () => void; // Callback when typing
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
interface ImagePlaceholder {
|
|
11
|
+
original: string;
|
|
12
|
+
placeholder: string;
|
|
13
|
+
type: 'img' | 'svg';
|
|
14
|
+
}
|
|
15
|
+
const TypingEffect: React.FC<TypingEffectProps> = ({ content, speed, onComplete, onUpdate }) => {
|
|
11
16
|
const [displayedContent, setDisplayedContent] = useState<string>('');
|
|
12
17
|
const [index, setIndex] = useState<number>(0);
|
|
18
|
+
const [imagePlaceholders, setImagePlaceholders] = useState<ImagePlaceholder[]>([]);
|
|
19
|
+
const [processedContent, setProcessedContent] = useState<string>('');
|
|
20
|
+
|
|
21
|
+
// Extract and replace image tags
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const extractImages = (html: string): { processedHtml: string; placeholders: ImagePlaceholder[] } => {
|
|
24
|
+
const placeholders: ImagePlaceholder[] = [];
|
|
25
|
+
let processedHtml = html;
|
|
26
|
+
|
|
27
|
+
// <img>
|
|
28
|
+
processedHtml = processedHtml.replace(/<img[^>]*>/g, (match) => {
|
|
29
|
+
const placeholder = `[IMG_${placeholders.length}]`;
|
|
30
|
+
placeholders.push({
|
|
31
|
+
original: match,
|
|
32
|
+
placeholder,
|
|
33
|
+
type: 'img'
|
|
34
|
+
});
|
|
35
|
+
return placeholder;
|
|
36
|
+
});
|
|
13
37
|
|
|
38
|
+
// <svg>
|
|
39
|
+
processedHtml = processedHtml.replace(/<svg[^>]*>[\s\S]*?<\/svg>/g, (match) => {
|
|
40
|
+
const placeholder = `[SVG_${placeholders.length}]`;
|
|
41
|
+
placeholders.push({
|
|
42
|
+
original: match,
|
|
43
|
+
placeholder,
|
|
44
|
+
type: 'svg'
|
|
45
|
+
});
|
|
46
|
+
return placeholder;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return { processedHtml, placeholders };
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const { processedHtml, placeholders } = extractImages(content);
|
|
53
|
+
setProcessedContent(processedHtml);
|
|
54
|
+
setImagePlaceholders(placeholders);
|
|
55
|
+
}, [content]);
|
|
56
|
+
|
|
57
|
+
// Handle typing effects
|
|
14
58
|
useEffect(() => {
|
|
15
59
|
const timer = setInterval(() => {
|
|
16
|
-
if (index <
|
|
17
|
-
|
|
60
|
+
if (index < processedContent.length) {
|
|
61
|
+
let newContent = processedContent.substring(0, index + 1);
|
|
62
|
+
|
|
63
|
+
// Replace the completed placeholder
|
|
64
|
+
imagePlaceholders.forEach(({ original, placeholder }) => {
|
|
65
|
+
if (newContent.includes(placeholder)) {
|
|
66
|
+
newContent = newContent.replace(placeholder, original);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
setDisplayedContent(newContent);
|
|
18
71
|
setIndex((prev) => prev + 1);
|
|
19
|
-
|
|
72
|
+
onUpdate?.();
|
|
20
73
|
} else {
|
|
21
74
|
clearInterval(timer);
|
|
22
|
-
onComplete?.();
|
|
75
|
+
onComplete?.();
|
|
23
76
|
}
|
|
24
77
|
}, speed);
|
|
25
78
|
|
|
26
|
-
return () => clearInterval(timer);
|
|
27
|
-
}, [
|
|
79
|
+
return () => clearInterval(timer);
|
|
80
|
+
}, [processedContent, index, speed, onComplete, onUpdate, imagePlaceholders]);
|
|
28
81
|
|
|
29
82
|
return <span dangerouslySetInnerHTML={{ __html: displayedContent }} />;
|
|
30
83
|
};
|