@xcelsior/ui-chat 2.0.3 → 2.0.4
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/.storybook/preview.tsx +2 -1
- package/dist/index.js +38 -53
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +66 -81
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
- package/src/components/Chat.tsx +35 -74
- package/src/components/ChatWidget.tsx +0 -1
- package/src/hooks/useMessages.ts +22 -1
- package/storybook-static/assets/Chat.stories-BkbpOOSG.js +830 -0
- package/storybook-static/assets/{Color-YHDXOIA2-BMnd3YrF.js → Color-YHDXOIA2-CSuNIR0a.js} +1 -1
- package/storybook-static/assets/{DocsRenderer-CFRXHY34-i_W8iCu9.js → DocsRenderer-CFRXHY34-dpuOKTQp.js} +3 -3
- package/storybook-static/assets/{MessageItem-DAaKZ9s9.js → MessageItem-Dlb6dSKL.js} +9 -9
- package/storybook-static/assets/MessageItem.stories-CsxqSqu-.js +422 -0
- package/storybook-static/assets/{entry-preview-oDnntGcx.js → entry-preview-C_-WO6GJ.js} +1 -1
- package/storybook-static/assets/{iframe-CGBtu2Se.js → iframe-BXTccXxS.js} +2 -2
- package/storybook-static/assets/preview-B8y-wc-n.css +1 -0
- package/storybook-static/assets/preview-CC4t7T7W.js +1 -0
- package/storybook-static/assets/{preview-BRpahs9B.js → preview-Cyx3pE7Q.js} +2 -2
- package/storybook-static/iframe.html +1 -1
- package/storybook-static/index.json +1 -1
- package/storybook-static/project.json +1 -1
- package/tsconfig.json +4 -0
- package/storybook-static/assets/Chat.stories-J_Yp51wU.js +0 -803
- package/storybook-static/assets/MessageItem.stories-Ckr1_scc.js +0 -255
- package/storybook-static/assets/ToastContext-Bty1K7ya.js +0 -1
- package/storybook-static/assets/preview-DUOvJmsz.js +0 -1
- package/storybook-static/assets/preview-DcGwT3kv.css +0 -1
package/.storybook/preview.tsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import '@xcelsior/design-system/styles';
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
4
4
|
import { ToastContainer } from '@xcelsior/design-system';
|
|
5
5
|
|
|
6
|
+
import type { Preview } from '@storybook/react';
|
|
6
7
|
const queryClient = new QueryClient({
|
|
7
8
|
defaultOptions: {
|
|
8
9
|
queries: {
|
package/dist/index.js
CHANGED
|
@@ -251,6 +251,7 @@ async function fetchMessages(baseUrl, params, headers) {
|
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
// src/hooks/useMessages.ts
|
|
254
|
+
var BOT_THINKING_TIMEOUT = 45e3;
|
|
254
255
|
function useMessages(websocket, config) {
|
|
255
256
|
const [messages, setMessages] = (0, import_react2.useState)([]);
|
|
256
257
|
const [isLoading, setIsLoading] = (0, import_react2.useState)(false);
|
|
@@ -259,6 +260,7 @@ function useMessages(websocket, config) {
|
|
|
259
260
|
const [hasMore, setHasMore] = (0, import_react2.useState)(true);
|
|
260
261
|
const [isLoadingMore, setIsLoadingMore] = (0, import_react2.useState)(false);
|
|
261
262
|
const [isBotThinking, setIsBotThinking] = (0, import_react2.useState)(false);
|
|
263
|
+
const botThinkingTimerRef = (0, import_react2.useRef)(null);
|
|
262
264
|
const { httpApiUrl, conversationId, headers, onError, toast } = config;
|
|
263
265
|
const headersWithApiKey = (0, import_react2.useMemo)(
|
|
264
266
|
() => ({
|
|
@@ -309,6 +311,10 @@ function useMessages(websocket, config) {
|
|
|
309
311
|
});
|
|
310
312
|
if (newMessage.senderType === "bot" || newMessage.senderType === "system") {
|
|
311
313
|
setIsBotThinking(false);
|
|
314
|
+
if (botThinkingTimerRef.current) {
|
|
315
|
+
clearTimeout(botThinkingTimerRef.current);
|
|
316
|
+
botThinkingTimerRef.current = null;
|
|
317
|
+
}
|
|
312
318
|
}
|
|
313
319
|
onMessageReceived?.(newMessage);
|
|
314
320
|
}
|
|
@@ -322,6 +328,10 @@ function useMessages(websocket, config) {
|
|
|
322
328
|
});
|
|
323
329
|
if (message.senderType === "customer") {
|
|
324
330
|
setIsBotThinking(true);
|
|
331
|
+
if (botThinkingTimerRef.current) clearTimeout(botThinkingTimerRef.current);
|
|
332
|
+
botThinkingTimerRef.current = setTimeout(() => {
|
|
333
|
+
setIsBotThinking(false);
|
|
334
|
+
}, BOT_THINKING_TIMEOUT);
|
|
325
335
|
}
|
|
326
336
|
}, []);
|
|
327
337
|
const updateMessageStatus = (0, import_react2.useCallback)((messageId, status) => {
|
|
@@ -365,6 +375,11 @@ function useMessages(websocket, config) {
|
|
|
365
375
|
headersWithApiKey,
|
|
366
376
|
onError
|
|
367
377
|
]);
|
|
378
|
+
(0, import_react2.useEffect)(() => {
|
|
379
|
+
return () => {
|
|
380
|
+
if (botThinkingTimerRef.current) clearTimeout(botThinkingTimerRef.current);
|
|
381
|
+
};
|
|
382
|
+
}, []);
|
|
368
383
|
return {
|
|
369
384
|
messages,
|
|
370
385
|
addMessage,
|
|
@@ -2640,7 +2655,6 @@ function ChatWidget({
|
|
|
2640
2655
|
})();
|
|
2641
2656
|
const positionClass = resolvedPosition === "left" ? "left-4" : "right-4";
|
|
2642
2657
|
const containerStyle = isFullPage ? { backgroundColor: bgColor, color: textColor } : {
|
|
2643
|
-
position: "relative",
|
|
2644
2658
|
width,
|
|
2645
2659
|
height,
|
|
2646
2660
|
maxHeight: "calc(100vh - 100px)",
|
|
@@ -3357,59 +3371,36 @@ function Chat({
|
|
|
3357
3371
|
const [userInfo, setUserInfo] = (0, import_react14.useState)(null);
|
|
3358
3372
|
const [conversationId, setConversationId] = (0, import_react14.useState)("");
|
|
3359
3373
|
const [isLoading, setIsLoading] = (0, import_react14.useState)(true);
|
|
3360
|
-
const [isAnimating, setIsAnimating] = (0, import_react14.useState)(false);
|
|
3361
|
-
const [showWidget, setShowWidget] = (0, import_react14.useState)(false);
|
|
3362
3374
|
const identityMode = config.identityCollection || "progressive";
|
|
3363
3375
|
const { position, isDragging, showHint, handlers } = useDraggablePosition(config.position);
|
|
3364
|
-
const
|
|
3376
|
+
const sessionInitializedRef = (0, import_react14.useRef)(false);
|
|
3377
|
+
const { currentState, setState } = useChatWidgetState({
|
|
3365
3378
|
state,
|
|
3366
3379
|
defaultState,
|
|
3367
3380
|
onStateChange
|
|
3368
3381
|
});
|
|
3369
|
-
const
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
setStateRaw(newState);
|
|
3375
|
-
requestAnimationFrame(() => {
|
|
3376
|
-
requestAnimationFrame(() => {
|
|
3377
|
-
setIsAnimating(false);
|
|
3378
|
-
});
|
|
3379
|
-
});
|
|
3380
|
-
} else if ((newState === "minimized" || newState === "closed") && currentState === "open") {
|
|
3381
|
-
setIsAnimating(true);
|
|
3382
|
-
setTimeout(() => {
|
|
3383
|
-
setShowWidget(false);
|
|
3384
|
-
setIsAnimating(false);
|
|
3385
|
-
setStateRaw(newState);
|
|
3386
|
-
}, 200);
|
|
3387
|
-
} else {
|
|
3388
|
-
setStateRaw(newState);
|
|
3389
|
-
}
|
|
3390
|
-
},
|
|
3391
|
-
[currentState, setStateRaw]
|
|
3392
|
-
);
|
|
3393
|
-
(0, import_react14.useEffect)(() => {
|
|
3394
|
-
if (currentState === "open") {
|
|
3395
|
-
setShowWidget(true);
|
|
3396
|
-
}
|
|
3397
|
-
}, [currentState]);
|
|
3382
|
+
const configConversationId = config.conversationId;
|
|
3383
|
+
const configUserEmail = config.currentUser?.email;
|
|
3384
|
+
const configUserName = config.currentUser?.name;
|
|
3385
|
+
const configUserAvatar = config.currentUser?.avatar;
|
|
3386
|
+
const configUserStatus = config.currentUser?.status;
|
|
3398
3387
|
(0, import_react14.useEffect)(() => {
|
|
3388
|
+
if (sessionInitializedRef.current) return;
|
|
3399
3389
|
const initializeSession = () => {
|
|
3400
3390
|
try {
|
|
3401
|
-
if (
|
|
3402
|
-
const convId2 =
|
|
3391
|
+
if (configUserEmail && configUserName) {
|
|
3392
|
+
const convId2 = configConversationId || generateSessionId();
|
|
3403
3393
|
const user = {
|
|
3404
|
-
name:
|
|
3405
|
-
email:
|
|
3406
|
-
avatar:
|
|
3394
|
+
name: configUserName,
|
|
3395
|
+
email: configUserEmail,
|
|
3396
|
+
avatar: configUserAvatar,
|
|
3407
3397
|
type: "customer",
|
|
3408
|
-
status:
|
|
3398
|
+
status: configUserStatus
|
|
3409
3399
|
};
|
|
3410
3400
|
setUserInfo(user);
|
|
3411
3401
|
setConversationId(convId2);
|
|
3412
3402
|
setIsLoading(false);
|
|
3403
|
+
sessionInitializedRef.current = true;
|
|
3413
3404
|
return;
|
|
3414
3405
|
}
|
|
3415
3406
|
const storedDataJson = localStorage.getItem(`${storageKeyPrefix}_user`);
|
|
@@ -3426,23 +3417,26 @@ function Chat({
|
|
|
3426
3417
|
setUserInfo(user);
|
|
3427
3418
|
setConversationId(storedData.conversationId);
|
|
3428
3419
|
setIsLoading(false);
|
|
3420
|
+
sessionInitializedRef.current = true;
|
|
3429
3421
|
return;
|
|
3430
3422
|
}
|
|
3431
3423
|
}
|
|
3432
|
-
const convId =
|
|
3424
|
+
const convId = configConversationId || generateSessionId();
|
|
3433
3425
|
setConversationId(convId);
|
|
3434
3426
|
if (identityMode === "progressive" || identityMode === "none") {
|
|
3435
3427
|
setUserInfo(null);
|
|
3436
3428
|
}
|
|
3429
|
+
sessionInitializedRef.current = true;
|
|
3437
3430
|
} catch (error) {
|
|
3438
3431
|
console.error("Error initializing chat session:", error);
|
|
3439
|
-
setConversationId(
|
|
3432
|
+
setConversationId(configConversationId || generateSessionId());
|
|
3433
|
+
sessionInitializedRef.current = true;
|
|
3440
3434
|
} finally {
|
|
3441
3435
|
setIsLoading(false);
|
|
3442
3436
|
}
|
|
3443
3437
|
};
|
|
3444
3438
|
initializeSession();
|
|
3445
|
-
}, [
|
|
3439
|
+
}, [configConversationId, configUserEmail, configUserName, configUserAvatar, configUserStatus, storageKeyPrefix, identityMode]);
|
|
3446
3440
|
const handlePreChatSubmit = (0, import_react14.useCallback)(
|
|
3447
3441
|
(name, email) => {
|
|
3448
3442
|
const convId = conversationId || generateSessionId();
|
|
@@ -3528,16 +3522,7 @@ function Chat({
|
|
|
3528
3522
|
conversationId,
|
|
3529
3523
|
currentUser: userInfo || void 0
|
|
3530
3524
|
};
|
|
3531
|
-
|
|
3532
|
-
opacity: 1,
|
|
3533
|
-
transform: "translateY(0) scale(1)",
|
|
3534
|
-
transition: "opacity 0.25s ease-out, transform 0.25s ease-out"
|
|
3535
|
-
} : {
|
|
3536
|
-
opacity: 0,
|
|
3537
|
-
transform: "translateY(12px) scale(0.97)",
|
|
3538
|
-
transition: "opacity 0.2s ease-in, transform 0.2s ease-in"
|
|
3539
|
-
};
|
|
3540
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: widgetAnimationStyle, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3525
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3541
3526
|
ChatWidget,
|
|
3542
3527
|
{
|
|
3543
3528
|
config: fullConfig,
|
|
@@ -3546,7 +3531,7 @@ function Chat({
|
|
|
3546
3531
|
onMinimize: () => setState("minimized"),
|
|
3547
3532
|
resolvedPosition: position
|
|
3548
3533
|
}
|
|
3549
|
-
)
|
|
3534
|
+
);
|
|
3550
3535
|
}
|
|
3551
3536
|
|
|
3552
3537
|
// src/components/TypingIndicator.tsx
|