@fusioni/client-sdk 1.1.10 → 1.1.12
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/dist/components/ChatWidget.d.ts.map +1 -1
- package/dist/components/FloatingButton.d.ts.map +1 -1
- package/dist/components/Message.d.ts.map +1 -1
- package/dist/fusioni-sdk.umd.js +120 -51
- package/dist/fusioni-sdk.umd.js.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +118 -49
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +118 -49
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -4955,11 +4955,12 @@ const DocumentVideoGrid = ({ videos, attachedVideosLabel, }) => {
|
|
|
4955
4955
|
// Module-level Set to track which message IDs have been animated
|
|
4956
4956
|
// This persists across component unmounts/remounts (e.g., when chat closes and reopens)
|
|
4957
4957
|
const animatedMessageIds = new Set();
|
|
4958
|
+
const TYPING_PREVIEW_CHARACTER_LIMIT = 200;
|
|
4958
4959
|
const Message = ({ message, showThoughts = false, fontSize = 'text-sm', onDelete, onConfirmation, enableButtons = true, apiBaseUrl, apiKey, agencyId, currentLanguage = 'en', onOpenGallery }) => {
|
|
4959
4960
|
const { t } = useTranslation(currentLanguage);
|
|
4960
4961
|
const [displayedContent, setDisplayedContent] = useState('');
|
|
4961
4962
|
const typingIntervalRef = useRef(null);
|
|
4962
|
-
const typingSpeed =
|
|
4963
|
+
const typingSpeed = 5; // milliseconds per character
|
|
4963
4964
|
const enhanceMessageContent = (content) => {
|
|
4964
4965
|
if (!content)
|
|
4965
4966
|
return content;
|
|
@@ -5109,6 +5110,7 @@ const Message = ({ message, showThoughts = false, fontSize = 'text-sm', onDelete
|
|
|
5109
5110
|
// Now animate through segments
|
|
5110
5111
|
let segmentIndex = 0;
|
|
5111
5112
|
let textIndex = 0;
|
|
5113
|
+
let typedCharacterCount = 0;
|
|
5112
5114
|
const nextTextStep = (text, index) => {
|
|
5113
5115
|
if (index >= text.length)
|
|
5114
5116
|
return { nextIndex: index, slice: '' };
|
|
@@ -5145,6 +5147,11 @@ const Message = ({ message, showThoughts = false, fontSize = 'text-sm', onDelete
|
|
|
5145
5147
|
typingIntervalRef.current = setTimeout(typeNextChar, 0);
|
|
5146
5148
|
}
|
|
5147
5149
|
else {
|
|
5150
|
+
if (typedCharacterCount >= TYPING_PREVIEW_CHARACTER_LIMIT) {
|
|
5151
|
+
setDisplayedContent(fullContent);
|
|
5152
|
+
animatedMessageIds.add(messageId);
|
|
5153
|
+
return;
|
|
5154
|
+
}
|
|
5148
5155
|
// Text segments are typed character by character
|
|
5149
5156
|
if (textIndex < segment.content.length) {
|
|
5150
5157
|
const step = nextTextStep(segment.content, textIndex);
|
|
@@ -5162,6 +5169,14 @@ const Message = ({ message, showThoughts = false, fontSize = 'text-sm', onDelete
|
|
|
5162
5169
|
content += step.slice;
|
|
5163
5170
|
setDisplayedContent(content);
|
|
5164
5171
|
textIndex = step.nextIndex;
|
|
5172
|
+
typedCharacterCount++;
|
|
5173
|
+
if (typedCharacterCount >= TYPING_PREVIEW_CHARACTER_LIMIT) {
|
|
5174
|
+
typingIntervalRef.current = setTimeout(() => {
|
|
5175
|
+
setDisplayedContent(fullContent);
|
|
5176
|
+
animatedMessageIds.add(messageId);
|
|
5177
|
+
}, typingSpeed);
|
|
5178
|
+
return;
|
|
5179
|
+
}
|
|
5165
5180
|
typingIntervalRef.current = setTimeout(typeNextChar, typingSpeed);
|
|
5166
5181
|
}
|
|
5167
5182
|
else {
|
|
@@ -5701,11 +5716,9 @@ const FloatingButton = ({ isOpen, onClick, position = 'bottom-right', primaryCol
|
|
|
5701
5716
|
const [showAttentionSequence, setShowAttentionSequence] = useState(false);
|
|
5702
5717
|
const [isAttentionActive, setIsAttentionActive] = useState(false);
|
|
5703
5718
|
useEffect(() => {
|
|
5704
|
-
// Sophisticated entrance animation
|
|
5705
5719
|
const entranceTimer = setTimeout(() => {
|
|
5706
5720
|
setIsVisible(true);
|
|
5707
5721
|
}, 200);
|
|
5708
|
-
// Periodic attention sequence (every 15 seconds)
|
|
5709
5722
|
const attentionInterval = setInterval(() => {
|
|
5710
5723
|
if (!isHovered && !isOpen) {
|
|
5711
5724
|
setShowAttentionSequence(true);
|
|
@@ -6089,6 +6102,33 @@ function useIsMobileLayout() {
|
|
|
6089
6102
|
return isMobile;
|
|
6090
6103
|
}
|
|
6091
6104
|
|
|
6105
|
+
const getStoredConversationIdKey = (agencyId) => `fusioni:selectedConversationId:${agencyId}`;
|
|
6106
|
+
const readStoredConversationId = (agencyId) => {
|
|
6107
|
+
if (typeof window === 'undefined')
|
|
6108
|
+
return null;
|
|
6109
|
+
try {
|
|
6110
|
+
return window.sessionStorage.getItem(getStoredConversationIdKey(agencyId));
|
|
6111
|
+
}
|
|
6112
|
+
catch {
|
|
6113
|
+
return null;
|
|
6114
|
+
}
|
|
6115
|
+
};
|
|
6116
|
+
const writeStoredConversationId = (agencyId, conversationId) => {
|
|
6117
|
+
if (typeof window === 'undefined')
|
|
6118
|
+
return;
|
|
6119
|
+
try {
|
|
6120
|
+
const key = getStoredConversationIdKey(agencyId);
|
|
6121
|
+
if (conversationId) {
|
|
6122
|
+
window.sessionStorage.setItem(key, conversationId);
|
|
6123
|
+
}
|
|
6124
|
+
else {
|
|
6125
|
+
window.sessionStorage.removeItem(key);
|
|
6126
|
+
}
|
|
6127
|
+
}
|
|
6128
|
+
catch {
|
|
6129
|
+
// Storage can be unavailable in restricted browser contexts.
|
|
6130
|
+
}
|
|
6131
|
+
};
|
|
6092
6132
|
const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMessageReceived, onConversationCreated, onConversationDeleted, onError }, ref) {
|
|
6093
6133
|
const [languageOverride, setLanguageOverride] = useState(null);
|
|
6094
6134
|
const [isOpen, setIsOpen] = useState(false);
|
|
@@ -6103,12 +6143,15 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6103
6143
|
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
|
|
6104
6144
|
const [messageToDelete, setMessageToDelete] = useState(null);
|
|
6105
6145
|
const [isDeleteMessageDialogOpen, setIsDeleteMessageDialogOpen] = useState(false);
|
|
6146
|
+
const [hasLoadedConversations, setHasLoadedConversations] = useState(false);
|
|
6106
6147
|
// Refs
|
|
6107
6148
|
const floatingButtonRef = useRef(null);
|
|
6149
|
+
const restoredConversationIdRef = useRef(null);
|
|
6108
6150
|
const translationDefault = languageOverride ?? mergedConfig?.language ?? config.language ?? 'en';
|
|
6109
6151
|
// Translation and language management - use merged config or fallback to user config
|
|
6110
6152
|
const { t, currentLanguage, changeLanguage } = useTranslation(translationDefault);
|
|
6111
|
-
const
|
|
6153
|
+
const activeAgencyId = mergedConfig?.agencyId || config.agencyId;
|
|
6154
|
+
const { conversations, currentConversation, messages, streamMessages, setCurrentConversation, setStreamMessages, addMessage, updateMessage, removeMessage, removeOptimisticUserMessages, truncateMessagesAt, addConversation, updateConversation, removeConversation, loadConversations, loadMessages, clearMessages } = useChatState(activeAgencyId);
|
|
6112
6155
|
const { theme, toggleTheme, setTheme } = useTheme(mergedConfig?.theme || config.theme);
|
|
6113
6156
|
const isMobileLayout = useIsMobileLayout();
|
|
6114
6157
|
const handleLanguageChange = useCallback((language) => {
|
|
@@ -6175,12 +6218,22 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6175
6218
|
}, [config, onError, t]);
|
|
6176
6219
|
// Load initial conversations
|
|
6177
6220
|
useEffect(() => {
|
|
6178
|
-
if (
|
|
6179
|
-
|
|
6221
|
+
if (activeAgencyId) {
|
|
6222
|
+
let isCancelled = false;
|
|
6223
|
+
restoredConversationIdRef.current = null;
|
|
6224
|
+
setHasLoadedConversations(false);
|
|
6225
|
+
loadConversations().finally(() => {
|
|
6226
|
+
if (!isCancelled) {
|
|
6227
|
+
setHasLoadedConversations(true);
|
|
6228
|
+
}
|
|
6229
|
+
});
|
|
6230
|
+
return () => {
|
|
6231
|
+
isCancelled = true;
|
|
6232
|
+
};
|
|
6180
6233
|
}
|
|
6181
|
-
}, [
|
|
6234
|
+
}, [activeAgencyId, loadConversations]);
|
|
6182
6235
|
// SSE connection for real-time updates - only when a chat panel is open
|
|
6183
|
-
useSSE(
|
|
6236
|
+
useSSE(activeAgencyId, (data) => {
|
|
6184
6237
|
// Same as fusioni-web chat.component: latest SSE line replaces stream (single loading row updates)
|
|
6185
6238
|
if (data?.data != null && String(data.data).trim() !== '') {
|
|
6186
6239
|
setStreamMessages([String(data.data)]);
|
|
@@ -6204,6 +6257,7 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6204
6257
|
const handleCreateConversation = useCallback(() => {
|
|
6205
6258
|
if (!mergedConfig)
|
|
6206
6259
|
return;
|
|
6260
|
+
writeStoredConversationId(activeAgencyId, null);
|
|
6207
6261
|
// Create a new conversation with null ID - will be created on server when first message is sent
|
|
6208
6262
|
const newConversation = {
|
|
6209
6263
|
id: null,
|
|
@@ -6219,7 +6273,7 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6219
6273
|
// Auto-hide conversation list when a new conversation is created
|
|
6220
6274
|
setIsConversationListOpen(false);
|
|
6221
6275
|
onConversationCreated?.(newConversation);
|
|
6222
|
-
}, [mergedConfig, addConversation, setCurrentConversation, clearMessages, onConversationCreated, t]);
|
|
6276
|
+
}, [activeAgencyId, mergedConfig, addConversation, setCurrentConversation, clearMessages, onConversationCreated, t]);
|
|
6223
6277
|
const handleSelectConversation = useCallback(async (conversation) => {
|
|
6224
6278
|
try {
|
|
6225
6279
|
setIsLoading(true);
|
|
@@ -6227,6 +6281,9 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6227
6281
|
clearMessages();
|
|
6228
6282
|
setStreamMessages([]);
|
|
6229
6283
|
setCurrentConversation(conversation);
|
|
6284
|
+
if (conversation.id) {
|
|
6285
|
+
writeStoredConversationId(activeAgencyId, conversation.id);
|
|
6286
|
+
}
|
|
6230
6287
|
// Auto-hide conversation list when a conversation is selected
|
|
6231
6288
|
setIsConversationListOpen(false);
|
|
6232
6289
|
if (conversation.id) {
|
|
@@ -6241,7 +6298,51 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6241
6298
|
finally {
|
|
6242
6299
|
setIsLoading(false);
|
|
6243
6300
|
}
|
|
6244
|
-
}, [setCurrentConversation, loadMessages, clearMessages, onError]);
|
|
6301
|
+
}, [activeAgencyId, setCurrentConversation, loadMessages, clearMessages, onError, t]);
|
|
6302
|
+
useEffect(() => {
|
|
6303
|
+
if (!hasLoadedConversations || !activeAgencyId || currentConversation) {
|
|
6304
|
+
return;
|
|
6305
|
+
}
|
|
6306
|
+
const storedConversationId = readStoredConversationId(activeAgencyId);
|
|
6307
|
+
if (!storedConversationId || restoredConversationIdRef.current === storedConversationId) {
|
|
6308
|
+
return;
|
|
6309
|
+
}
|
|
6310
|
+
restoredConversationIdRef.current = storedConversationId;
|
|
6311
|
+
let isCancelled = false;
|
|
6312
|
+
const restoreConversation = async () => {
|
|
6313
|
+
let storedConversation = conversations.find((conversation) => conversation.id === storedConversationId);
|
|
6314
|
+
if (!storedConversation) {
|
|
6315
|
+
try {
|
|
6316
|
+
storedConversation = await getConversationService().getConversation(storedConversationId);
|
|
6317
|
+
}
|
|
6318
|
+
catch {
|
|
6319
|
+
storedConversation = undefined;
|
|
6320
|
+
}
|
|
6321
|
+
}
|
|
6322
|
+
if (isCancelled) {
|
|
6323
|
+
return;
|
|
6324
|
+
}
|
|
6325
|
+
if (!storedConversation) {
|
|
6326
|
+
writeStoredConversationId(activeAgencyId, null);
|
|
6327
|
+
return;
|
|
6328
|
+
}
|
|
6329
|
+
if (!conversations.some((conversation) => conversation.id === storedConversation?.id)) {
|
|
6330
|
+
addConversation(storedConversation);
|
|
6331
|
+
}
|
|
6332
|
+
handleSelectConversation(storedConversation);
|
|
6333
|
+
};
|
|
6334
|
+
restoreConversation();
|
|
6335
|
+
return () => {
|
|
6336
|
+
isCancelled = true;
|
|
6337
|
+
};
|
|
6338
|
+
}, [
|
|
6339
|
+
addConversation,
|
|
6340
|
+
activeAgencyId,
|
|
6341
|
+
conversations,
|
|
6342
|
+
currentConversation,
|
|
6343
|
+
handleSelectConversation,
|
|
6344
|
+
hasLoadedConversations
|
|
6345
|
+
]);
|
|
6245
6346
|
const handleDeleteConversation = useCallback((conversationId) => {
|
|
6246
6347
|
setConversationToDelete(conversationId);
|
|
6247
6348
|
setIsDeleteDialogOpen(true);
|
|
@@ -6254,6 +6355,9 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6254
6355
|
const conversationService = getConversationService();
|
|
6255
6356
|
await conversationService.deleteConversation(conversationToDelete);
|
|
6256
6357
|
removeConversation(conversationToDelete);
|
|
6358
|
+
if (readStoredConversationId(activeAgencyId) === conversationToDelete) {
|
|
6359
|
+
writeStoredConversationId(activeAgencyId, null);
|
|
6360
|
+
}
|
|
6257
6361
|
if (currentConversation?.id === conversationToDelete) {
|
|
6258
6362
|
setCurrentConversation(null);
|
|
6259
6363
|
clearMessages();
|
|
@@ -6275,7 +6379,7 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6275
6379
|
finally {
|
|
6276
6380
|
setIsLoading(false);
|
|
6277
6381
|
}
|
|
6278
|
-
}, [conversationToDelete, removeConversation, currentConversation, setCurrentConversation, clearMessages, setStreamMessages, onConversationDeleted, onError, t]);
|
|
6382
|
+
}, [activeAgencyId, conversationToDelete, removeConversation, currentConversation, setCurrentConversation, clearMessages, setStreamMessages, onConversationDeleted, onError, t]);
|
|
6279
6383
|
const cancelDeleteConversation = useCallback(() => {
|
|
6280
6384
|
setIsDeleteDialogOpen(false);
|
|
6281
6385
|
setConversationToDelete(null);
|
|
@@ -6283,21 +6387,7 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6283
6387
|
const handleSendMessage = useCallback(async (content, image, audio, messageId) => {
|
|
6284
6388
|
if (!mergedConfig)
|
|
6285
6389
|
return;
|
|
6286
|
-
// Debug logging for conversation state
|
|
6287
|
-
console.log('🔍 ChatWidget.handleSendMessage - Starting message send:', {
|
|
6288
|
-
currentConversation: currentConversation,
|
|
6289
|
-
conversationId: currentConversation?.id,
|
|
6290
|
-
content: content?.substring(0, 100) + (content?.length > 100 ? '...' : ''),
|
|
6291
|
-
hasImage: !!image,
|
|
6292
|
-
hasAudio: !!audio,
|
|
6293
|
-
agencyId: mergedConfig.agencyId
|
|
6294
|
-
});
|
|
6295
6390
|
if (!currentConversation || (!content.trim() && !audio)) {
|
|
6296
|
-
console.warn('⚠️ ChatWidget.handleSendMessage - Early return:', {
|
|
6297
|
-
hasCurrentConversation: !!currentConversation,
|
|
6298
|
-
hasContent: !!content?.trim(),
|
|
6299
|
-
hasAudio: !!audio
|
|
6300
|
-
});
|
|
6301
6391
|
return;
|
|
6302
6392
|
}
|
|
6303
6393
|
try {
|
|
@@ -6305,18 +6395,11 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6305
6395
|
let conversationId = currentConversation.id;
|
|
6306
6396
|
// If this is a new conversation (null ID), create it on the server first
|
|
6307
6397
|
if (!conversationId) {
|
|
6308
|
-
console.log('🔍 ChatWidget.handleSendMessage - Creating server conversation for new conversation:', {
|
|
6309
|
-
agencyId: mergedConfig.agencyId
|
|
6310
|
-
});
|
|
6311
6398
|
const conversationService = getConversationService();
|
|
6312
6399
|
conversationId = await conversationService.createConversation({
|
|
6313
6400
|
title: t('chat.conversations.newConversation'),
|
|
6314
6401
|
agency_id: mergedConfig.agencyId,
|
|
6315
6402
|
});
|
|
6316
|
-
console.log('🔍 ChatWidget.handleSendMessage - Server conversation created:', {
|
|
6317
|
-
conversationId: conversationId,
|
|
6318
|
-
conversationIdType: typeof conversationId
|
|
6319
|
-
});
|
|
6320
6403
|
// Update the conversation with the real server ID
|
|
6321
6404
|
const updatedConversation = {
|
|
6322
6405
|
...currentConversation,
|
|
@@ -6325,10 +6408,7 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6325
6408
|
// Update the conversation in the list and set as current
|
|
6326
6409
|
updateConversation(updatedConversation.id, updatedConversation);
|
|
6327
6410
|
setCurrentConversation(updatedConversation);
|
|
6328
|
-
|
|
6329
|
-
conversationId: conversationId,
|
|
6330
|
-
updatedConversation: updatedConversation
|
|
6331
|
-
});
|
|
6411
|
+
writeStoredConversationId(activeAgencyId, conversationId);
|
|
6332
6412
|
}
|
|
6333
6413
|
// Clear stream messages for new conversation
|
|
6334
6414
|
setStreamMessages([]);
|
|
@@ -6382,7 +6462,6 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6382
6462
|
if (userMessage) {
|
|
6383
6463
|
onMessageSent?.(userMessage);
|
|
6384
6464
|
}
|
|
6385
|
-
// Debug logging before pipeline execution
|
|
6386
6465
|
const pipelineRequest = {
|
|
6387
6466
|
conversation_id: conversationId,
|
|
6388
6467
|
agency_id: mergedConfig.agencyId,
|
|
@@ -6391,14 +6470,6 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6391
6470
|
audio,
|
|
6392
6471
|
message_id: messageId
|
|
6393
6472
|
};
|
|
6394
|
-
console.log('🔍 ChatWidget.handleSendMessage - About to call executePipeline:', {
|
|
6395
|
-
conversationId: conversationId,
|
|
6396
|
-
conversationIdType: typeof conversationId,
|
|
6397
|
-
conversationIdLength: conversationId?.length,
|
|
6398
|
-
isNewConversation: !conversationId,
|
|
6399
|
-
pipelineRequest: pipelineRequest,
|
|
6400
|
-
currentConversation: currentConversation
|
|
6401
|
-
});
|
|
6402
6473
|
// Execute pipeline - this calls /pipeline/${agency_id}/exec
|
|
6403
6474
|
const pipelineService = getPipelineService();
|
|
6404
6475
|
const response = await pipelineService.executePipeline(pipelineRequest);
|
|
@@ -6450,6 +6521,7 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6450
6521
|
}
|
|
6451
6522
|
}, [
|
|
6452
6523
|
currentConversation,
|
|
6524
|
+
activeAgencyId,
|
|
6453
6525
|
mergedConfig,
|
|
6454
6526
|
messages,
|
|
6455
6527
|
addMessage,
|
|
@@ -6609,10 +6681,7 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
|
|
|
6609
6681
|
if (error) {
|
|
6610
6682
|
return (jsxs("div", { className: "fusioni-chat-error", children: [jsxs("p", { children: [t('common.error'), ": ", error] }), jsx("button", { onClick: () => setError(null), children: t('chat.errors.retry') })] }));
|
|
6611
6683
|
}
|
|
6612
|
-
|
|
6613
|
-
console.log('Primary color being applied:', mergedConfig.primaryColor || '#6366f1');
|
|
6614
|
-
console.log('Button variant being applied:', mergedConfig.buttonVariant || 'glass');
|
|
6615
|
-
return (jsxs("div", { className: `fusioni-chat-widget ${theme}`, style: { '--primary-color': mergedConfig.primaryColor || '#6366f1' }, children: [jsx(FloatingButton, { isOpen: isOpen, onClick: handleToggleChat, position: mergedConfig.position || 'bottom-right', primaryColor: mergedConfig.primaryColor, buttonRef: floatingButtonRef, variant: mergedConfig.buttonVariant || 'glass', shouldDisplay: !hasConfigError && (!isMobileLayout || !isOpen) }), isOpen && (jsx(ChatPanel, { isOpen: isOpen, onClose: () => setIsOpen(false), position: mergedConfig.position || 'bottom-right', isFullscreen: isFullscreen, floatingButtonRef: floatingButtonRef, children: jsxs("div", { className: "fusioni-chat-container", children: [mergedConfig.showConversationList !== false && (jsxs(Fragment, { children: [jsx("div", { className: `fusioni-conversation-backdrop ${isConversationListOpen ? 'open' : ''}`, onClick: () => setIsConversationListOpen(false) }), jsx(ConversationList, { conversations: conversations, selectedConversationId: currentConversation?.id || undefined, onSelectConversation: handleSelectConversation, onDeleteConversation: handleDeleteConversation, onCreateConversation: handleCreateConversation, isOpen: isConversationListOpen, currentLanguage: currentLanguage })] })), jsxs("div", { className: "fusioni-chat-main", children: [jsxs("div", { className: "fusioni-chat-main-header", children: [mergedConfig.showConversationList !== false ? (jsxs("button", { type: "button", onClick: handleToggleConversationList, className: `fusioni-conversation-toggle ${isConversationListOpen ? 'open' : ''}`, children: [jsx("svg", { className: "fusioni-conversation-toggle-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M3 12h18M3 6h18M3 18h18" }) }), t('chat.conversations.title')] })) : (jsx("span", { className: "fusioni-chat-main-header-title", children: t('chat.title') })), jsxs("div", { className: "fusioni-header-actions", children: [isMobileLayout && (jsx("button", { type: "button", onClick: () => setIsOpen(false), className: "fusioni-btn fusioni-btn-icon fusioni-chat-toolbar-close-mobile", title: t('common.close'), "aria-label": t('common.close'), children: jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", children: jsx("path", { d: "M18 6L6 18M6 6L18 18", strokeLinecap: "round", strokeLinejoin: "round" }) }) })), mergedConfig.showThemeToggle !== false && (jsx("button", { type: "button", onClick: toggleTheme, className: "fusioni-btn fusioni-btn-icon", title: theme === 'dark' ? t('chat.theme.light') : t('chat.theme.dark'), children: theme === 'dark' ? (jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [jsx("circle", { cx: "12", cy: "12", r: "5" }), jsx("line", { x1: "12", y1: "1", x2: "12", y2: "3" }), jsx("line", { x1: "12", y1: "21", x2: "12", y2: "23" }), jsx("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }), jsx("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }), jsx("line", { x1: "1", y1: "12", x2: "3", y2: "12" }), jsx("line", { x1: "21", y1: "12", x2: "23", y2: "12" }), jsx("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }), jsx("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })] })) : (jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) })) })), mergedConfig.showFullscreenToggle !== false && (jsx("button", { type: "button", onClick: handleToggleFullscreen, className: "fusioni-btn fusioni-btn-icon", title: isFullscreen ? t('chat.fullscreen.exit') : t('chat.fullscreen.enter'), children: isFullscreen ? (jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M8 3V5M8 3H5M8 3L3 8M16 3V5M16 3H19M16 3L21 8M8 21V19M8 21H5M8 21L3 16M16 21V19M16 21H19M16 21L21 16" }) })) : (jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M8 3H5C4.46957 3 3.96086 3.21071 3.58579 3.58579C3.21071 3.96086 3 4.46957 3 5V8M21 8V5C21 4.46957 20.7893 3.96086 20.4142 3.58579C20.0391 3.21071 19.5304 3 19 3H16M16 21H19C19.5304 21 20.0391 20.7893 20.4142 20.4142C20.7893 20.0391 21 19.5304 21 19V16M3 16V19C3 19.5304 3.21071 20.0391 3.58579 20.4142C3.96086 20.7893 4.46957 21 5 21H8" }) })) })), mergedConfig.showLanguageSwitcher !== false && (jsx(LanguageSwitcher, { currentLanguage: currentLanguage, onLanguageChange: handleLanguageChange }))] })] }), currentConversation ? (jsxs(Fragment, { children: [jsx(MessageList, { messages: messages, streamMessages: streamMessages, showThoughts: false, onDeleteMessage: handleDeleteMessage, onEditMessage: handleEditMessage, onConfirmation: handleConfirmation, enableButtons: !isLoading, apiBaseUrl: mergedConfig.apiBaseUrl, apiKey: mergedConfig.accessToken, agencyId: mergedConfig.agencyId, currentLanguage: currentLanguage, theme: theme }), jsx(ChatInput, { onSendMessage: handleSendMessage, onFileUpload: handleFileUpload, disabled: isLoading, placeholder: t('chat.input.placeholder'), enableAudioRecording: mergedConfig.enableAudioRecording !== false, enableFileUpload: mergedConfig.enableFileUpload !== false, maxFileSize: mergedConfig.maxFileSize || 10, allowedFileTypes: mergedConfig.allowedFileTypes || ['image/*'], currentLanguage: currentLanguage })] })) : (jsx("div", { className: "fusioni-chat-welcome", children: jsxs("div", { className: "fusioni-chat-welcome-content", children: [jsx("h3", { children: t('chat.welcome.title') }), jsx("p", { children: t('chat.welcome.description') }), jsx("button", { onClick: handleCreateConversation, disabled: isLoading, className: "fusioni-btn fusioni-btn-primary", children: isLoading ? t('chat.welcome.creating') : t('chat.welcome.startButton') })] }) }))] })] }) })), jsx(ConfirmationDialog, { isOpen: isDeleteDialogOpen, title: t('chat.conversations.deleteConfirm.title'), message: t('chat.conversations.deleteConfirm.message'), confirmText: t('chat.conversations.deleteConfirm.confirm'), cancelText: t('chat.conversations.deleteConfirm.cancel'), onConfirm: confirmDeleteConversation, onCancel: cancelDeleteConversation, currentLanguage: currentLanguage, variant: "danger" }), jsx(ConfirmationDialog, { isOpen: isDeleteMessageDialogOpen, title: t('chat.messages.deleteConfirm.title'), message: t('chat.messages.deleteConfirm.message'), confirmText: t('chat.messages.deleteConfirm.confirm'), cancelText: t('chat.messages.deleteConfirm.cancel'), onConfirm: confirmDeleteMessage, onCancel: cancelDeleteMessage, currentLanguage: currentLanguage, variant: "danger" })] }));
|
|
6684
|
+
return (jsxs("div", { className: `fusioni-chat-widget ${theme}`, style: { '--primary-color': mergedConfig.primaryColor || '#6366f1' }, children: [jsx(FloatingButton, { isOpen: isOpen, onClick: handleToggleChat, position: mergedConfig.position || 'bottom-right', primaryColor: mergedConfig.primaryColor, buttonRef: floatingButtonRef, variant: mergedConfig.buttonVariant || 'glass', shouldDisplay: !hasConfigError && (!isMobileLayout || !isOpen) }), isOpen && (jsx(ChatPanel, { isOpen: isOpen, onClose: () => setIsOpen(false), position: mergedConfig.position || 'bottom-right', isFullscreen: isFullscreen, floatingButtonRef: floatingButtonRef, children: jsxs("div", { className: "fusioni-chat-container", children: [mergedConfig.showConversationList !== false && (jsxs(Fragment, { children: [jsx("div", { className: `fusioni-conversation-backdrop ${isConversationListOpen ? 'open' : ''}`, onClick: () => setIsConversationListOpen(false) }), jsx(ConversationList, { conversations: conversations, selectedConversationId: currentConversation?.id || undefined, onSelectConversation: handleSelectConversation, onDeleteConversation: handleDeleteConversation, onCreateConversation: handleCreateConversation, isOpen: isConversationListOpen, currentLanguage: currentLanguage })] })), jsxs("div", { className: "fusioni-chat-main", children: [jsxs("div", { className: "fusioni-chat-main-header", children: [mergedConfig.showConversationList !== false ? (jsxs("button", { type: "button", onClick: handleToggleConversationList, className: `fusioni-conversation-toggle ${isConversationListOpen ? 'open' : ''}`, children: [jsx("svg", { className: "fusioni-conversation-toggle-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M3 12h18M3 6h18M3 18h18" }) }), t('chat.conversations.title')] })) : (jsx("span", { className: "fusioni-chat-main-header-title", children: t('chat.title') })), jsxs("div", { className: "fusioni-header-actions", children: [mergedConfig.showThemeToggle !== false && (jsx("button", { type: "button", onClick: toggleTheme, className: "fusioni-btn fusioni-btn-icon", title: theme === 'dark' ? t('chat.theme.light') : t('chat.theme.dark'), children: theme === 'dark' ? (jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [jsx("circle", { cx: "12", cy: "12", r: "5" }), jsx("line", { x1: "12", y1: "1", x2: "12", y2: "3" }), jsx("line", { x1: "12", y1: "21", x2: "12", y2: "23" }), jsx("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }), jsx("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }), jsx("line", { x1: "1", y1: "12", x2: "3", y2: "12" }), jsx("line", { x1: "21", y1: "12", x2: "23", y2: "12" }), jsx("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }), jsx("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })] })) : (jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) })) })), mergedConfig.showFullscreenToggle !== false && (jsx("button", { type: "button", onClick: handleToggleFullscreen, className: "fusioni-btn fusioni-btn-icon", title: isFullscreen ? t('chat.fullscreen.exit') : t('chat.fullscreen.enter'), children: isFullscreen ? (jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M8 3V5M8 3H5M8 3L3 8M16 3V5M16 3H19M16 3L21 8M8 21V19M8 21H5M8 21L3 16M16 21V19M16 21H19M16 21L21 16" }) })) : (jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M8 3H5C4.46957 3 3.96086 3.21071 3.58579 3.58579C3.21071 3.96086 3 4.46957 3 5V8M21 8V5C21 4.46957 20.7893 3.96086 20.4142 3.58579C20.0391 3.21071 19.5304 3 19 3H16M16 21H19C19.5304 21 20.0391 20.7893 20.4142 20.4142C20.7893 20.0391 21 19.5304 21 19V16M3 16V19C3 19.5304 3.21071 20.0391 3.58579 20.4142C3.96086 20.7893 4.46957 21 5 21H8" }) })) })), mergedConfig.showLanguageSwitcher !== false && (jsx(LanguageSwitcher, { currentLanguage: currentLanguage, onLanguageChange: handleLanguageChange })), jsx("button", { type: "button", onClick: () => setIsOpen(false), className: "fusioni-btn fusioni-btn-icon fusioni-chat-toolbar-close-mobile", title: t('common.close'), "aria-label": t('common.close'), children: jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", children: jsx("path", { d: "M18 6L6 18M6 6L18 18", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }), currentConversation ? (jsxs(Fragment, { children: [jsx(MessageList, { messages: messages, streamMessages: streamMessages, showThoughts: false, onDeleteMessage: handleDeleteMessage, onEditMessage: handleEditMessage, onConfirmation: handleConfirmation, enableButtons: !isLoading, apiBaseUrl: mergedConfig.apiBaseUrl, apiKey: mergedConfig.accessToken, agencyId: mergedConfig.agencyId, currentLanguage: currentLanguage, theme: theme }), jsx(ChatInput, { onSendMessage: handleSendMessage, onFileUpload: handleFileUpload, disabled: isLoading, placeholder: t('chat.input.placeholder'), enableAudioRecording: mergedConfig.enableAudioRecording !== false, enableFileUpload: mergedConfig.enableFileUpload !== false, maxFileSize: mergedConfig.maxFileSize || 10, allowedFileTypes: mergedConfig.allowedFileTypes || ['image/*'], currentLanguage: currentLanguage })] })) : (jsx("div", { className: "fusioni-chat-welcome", children: jsxs("div", { className: "fusioni-chat-welcome-content", children: [jsx("h3", { children: t('chat.welcome.title') }), jsx("p", { children: t('chat.welcome.description') }), jsx("button", { onClick: handleCreateConversation, disabled: isLoading, className: "fusioni-btn fusioni-btn-primary", children: isLoading ? t('chat.welcome.creating') : t('chat.welcome.startButton') })] }) }))] })] }) })), jsx(ConfirmationDialog, { isOpen: isDeleteDialogOpen, title: t('chat.conversations.deleteConfirm.title'), message: t('chat.conversations.deleteConfirm.message'), confirmText: t('chat.conversations.deleteConfirm.confirm'), cancelText: t('chat.conversations.deleteConfirm.cancel'), onConfirm: confirmDeleteConversation, onCancel: cancelDeleteConversation, currentLanguage: currentLanguage, variant: "danger" }), jsx(ConfirmationDialog, { isOpen: isDeleteMessageDialogOpen, title: t('chat.messages.deleteConfirm.title'), message: t('chat.messages.deleteConfirm.message'), confirmText: t('chat.messages.deleteConfirm.confirm'), cancelText: t('chat.messages.deleteConfirm.cancel'), onConfirm: confirmDeleteMessage, onCancel: cancelDeleteMessage, currentLanguage: currentLanguage, variant: "danger" })] }));
|
|
6616
6685
|
});
|
|
6617
6686
|
ChatWidget.displayName = 'ChatWidget';
|
|
6618
6687
|
|