@aslaluroba/help-center-react 3.2.3 → 3.2.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/dist/index.css +1 -1
- package/dist/index.esm.js +95 -86
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +95 -86
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/api.ts +0 -1
- package/src/ui/chatbot-popup/chat-window-screen/footer.tsx +107 -96
- package/src/ui/chatbot-popup/chat-window-screen/index.tsx +1 -1
package/dist/index.js
CHANGED
|
@@ -38390,6 +38390,7 @@ var ChatWindowFooter = props => {
|
|
|
38390
38390
|
var fileInputRef = React.useRef(null);
|
|
38391
38391
|
var [selectedFiles, setSelectedFiles] = React.useState([]);
|
|
38392
38392
|
var [previewImage, setPreviewImage] = React.useState(null);
|
|
38393
|
+
var [isSending, setIsSending] = React.useState(false);
|
|
38393
38394
|
var handleAttachClick = React.useCallback(() => {
|
|
38394
38395
|
var _a;
|
|
38395
38396
|
(_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
@@ -38425,106 +38426,112 @@ var ChatWindowFooter = props => {
|
|
|
38425
38426
|
}, []);
|
|
38426
38427
|
var handleSendMessageWithAttachments = React.useCallback(/*#__PURE__*/_asyncToGenerator(function* () {
|
|
38427
38428
|
// Prevent sending if already loading
|
|
38428
|
-
if (props.isLoading) {
|
|
38429
|
+
if (props.isLoading || isSending) {
|
|
38429
38430
|
return;
|
|
38430
38431
|
}
|
|
38431
|
-
|
|
38432
|
-
|
|
38433
|
-
|
|
38434
|
-
|
|
38435
|
-
|
|
38436
|
-
|
|
38437
|
-
|
|
38438
|
-
//
|
|
38439
|
-
|
|
38440
|
-
|
|
38441
|
-
|
|
38442
|
-
|
|
38443
|
-
sessionId
|
|
38444
|
-
|
|
38432
|
+
setIsSending(true);
|
|
38433
|
+
try {
|
|
38434
|
+
// Get files that need to be uploaded (those without uploadedId)
|
|
38435
|
+
var filesToUpload = selectedFiles.filter(f => f.uploadedId === null && !f.error);
|
|
38436
|
+
var alreadyUploadedIds = selectedFiles.filter(f => f.uploadedId !== null).map(f => f.uploadedId);
|
|
38437
|
+
// Declare uploadedIds outside the if block so it's accessible later
|
|
38438
|
+
var uploadedIds = [];
|
|
38439
|
+
// If there are files to upload, upload them first
|
|
38440
|
+
if (filesToUpload.length > 0) {
|
|
38441
|
+
// Get session ID - ensure session exists if needed (for image-only messages)
|
|
38442
|
+
var sessionId = null;
|
|
38443
|
+
try {
|
|
38444
|
+
// Use existing sessionId if available, otherwise ensure session is created
|
|
38445
|
+
if (props.sessionId) {
|
|
38446
|
+
sessionId = props.sessionId;
|
|
38447
|
+
} else {
|
|
38448
|
+
// Ensure session exists before uploading files (allows starting chat with image only)
|
|
38449
|
+
sessionId = yield props.onEnsureSession();
|
|
38450
|
+
}
|
|
38451
|
+
} catch (error) {
|
|
38452
|
+
console.error('[ChatWindowFooter] Failed to get sessionId for file upload:', error);
|
|
38445
38453
|
// Mark all files as error
|
|
38446
38454
|
setSelectedFiles(prev => prev.map(f => filesToUpload.some(ftl => ftl.previewUrl === f.previewUrl) ? _objectSpread2(_objectSpread2({}, f), {}, {
|
|
38447
|
-
error: '
|
|
38455
|
+
error: 'Failed to initialize session',
|
|
38448
38456
|
uploading: false
|
|
38449
38457
|
}) : f));
|
|
38458
|
+
setIsSending(false);
|
|
38450
38459
|
return;
|
|
38451
38460
|
}
|
|
38452
|
-
|
|
38453
|
-
|
|
38454
|
-
|
|
38455
|
-
|
|
38456
|
-
|
|
38457
|
-
|
|
38458
|
-
|
|
38459
|
-
|
|
38460
|
-
|
|
38461
|
-
|
|
38462
|
-
|
|
38463
|
-
|
|
38464
|
-
|
|
38465
|
-
|
|
38466
|
-
|
|
38467
|
-
|
|
38468
|
-
|
|
38469
|
-
|
|
38470
|
-
|
|
38471
|
-
|
|
38472
|
-
|
|
38473
|
-
|
|
38474
|
-
|
|
38475
|
-
headers: {
|
|
38476
|
-
'Content-Type': fileDto.file.type
|
|
38477
|
-
},
|
|
38478
|
-
onUploadProgress: () => {
|
|
38479
|
-
// Upload progress tracking (silent)
|
|
38461
|
+
// Upload each file and collect uploaded IDs
|
|
38462
|
+
uploadedIds = [];
|
|
38463
|
+
var hasUploadErrors = false;
|
|
38464
|
+
var _loop = function* _loop(fileDto) {
|
|
38465
|
+
try {
|
|
38466
|
+
// Mark as uploading
|
|
38467
|
+
setSelectedFiles(prev => prev.map(f => f.previewUrl === fileDto.previewUrl ? _objectSpread2(_objectSpread2({}, f), {}, {
|
|
38468
|
+
uploading: true,
|
|
38469
|
+
error: null
|
|
38470
|
+
}) : f));
|
|
38471
|
+
// Get presigned URL
|
|
38472
|
+
var presignResponse = yield presignUpload(sessionId, fileDto.file, i18n.language);
|
|
38473
|
+
// Upload file to presigned URL using axios
|
|
38474
|
+
var uploadResponse = yield axios$1.put(presignResponse.uploadUrl, fileDto.file, {
|
|
38475
|
+
headers: {
|
|
38476
|
+
'Content-Type': fileDto.file.type
|
|
38477
|
+
},
|
|
38478
|
+
onUploadProgress: () => {
|
|
38479
|
+
// Upload progress tracking (silent)
|
|
38480
|
+
}
|
|
38481
|
+
});
|
|
38482
|
+
if (uploadResponse.status !== 200 && uploadResponse.status !== 204) {
|
|
38483
|
+
throw new Error("Upload failed with status ".concat(uploadResponse.status));
|
|
38480
38484
|
}
|
|
38481
|
-
|
|
38482
|
-
|
|
38483
|
-
|
|
38484
|
-
|
|
38485
|
-
|
|
38486
|
-
|
|
38487
|
-
|
|
38488
|
-
|
|
38489
|
-
|
|
38490
|
-
|
|
38491
|
-
|
|
38492
|
-
|
|
38493
|
-
|
|
38494
|
-
|
|
38495
|
-
|
|
38496
|
-
|
|
38497
|
-
|
|
38498
|
-
|
|
38499
|
-
|
|
38500
|
-
|
|
38485
|
+
// Collect uploaded ID
|
|
38486
|
+
uploadedIds.push(presignResponse.id);
|
|
38487
|
+
// Update with uploaded ID
|
|
38488
|
+
setSelectedFiles(prev => prev.map(f => f.previewUrl === fileDto.previewUrl ? _objectSpread2(_objectSpread2({}, f), {}, {
|
|
38489
|
+
uploading: false,
|
|
38490
|
+
uploadedId: presignResponse.id,
|
|
38491
|
+
error: null
|
|
38492
|
+
}) : f));
|
|
38493
|
+
} catch (error) {
|
|
38494
|
+
console.error('[ChatWindowFooter] File upload failed:', error);
|
|
38495
|
+
hasUploadErrors = true;
|
|
38496
|
+
setSelectedFiles(prev => prev.map(f => f.previewUrl === fileDto.previewUrl ? _objectSpread2(_objectSpread2({}, f), {}, {
|
|
38497
|
+
uploading: false,
|
|
38498
|
+
error: 'Upload failed',
|
|
38499
|
+
uploadedId: null
|
|
38500
|
+
}) : f));
|
|
38501
|
+
}
|
|
38502
|
+
};
|
|
38503
|
+
for (var fileDto of filesToUpload) {
|
|
38504
|
+
yield* _loop(fileDto);
|
|
38505
|
+
}
|
|
38506
|
+
// If any uploads failed, don't send the message
|
|
38507
|
+
if (hasUploadErrors) {
|
|
38508
|
+
console.error('[ChatWindowFooter] Some files failed to upload, not sending message');
|
|
38509
|
+
setIsSending(false);
|
|
38510
|
+
return;
|
|
38501
38511
|
}
|
|
38502
|
-
};
|
|
38503
|
-
for (var fileDto of filesToUpload) {
|
|
38504
|
-
yield* _loop(fileDto);
|
|
38505
|
-
}
|
|
38506
|
-
// If any uploads failed, don't send the message
|
|
38507
|
-
if (hasUploadErrors) {
|
|
38508
|
-
console.error('[ChatWindowFooter] Some files failed to upload, not sending message');
|
|
38509
|
-
return;
|
|
38510
38512
|
}
|
|
38513
|
+
// Get all successfully uploaded file IDs (already uploaded + newly uploaded)
|
|
38514
|
+
// Use uploadedIds from the upload loop instead of reading from state
|
|
38515
|
+
var allAttachmentIds = [...alreadyUploadedIds, ...uploadedIds];
|
|
38516
|
+
// Call the original send message with attachment IDs
|
|
38517
|
+
props.handleSendMessage(allAttachmentIds);
|
|
38518
|
+
// Clear selected files and revoke URLs
|
|
38519
|
+
selectedFiles.forEach(f => URL.revokeObjectURL(f.previewUrl));
|
|
38520
|
+
setSelectedFiles([]);
|
|
38521
|
+
setIsSending(false);
|
|
38522
|
+
} catch (error) {
|
|
38523
|
+
console.error('[ChatWindowFooter] Error sending message:', error);
|
|
38524
|
+
setIsSending(false);
|
|
38511
38525
|
}
|
|
38512
|
-
|
|
38513
|
-
// Use uploadedIds from the upload loop instead of reading from state
|
|
38514
|
-
var allAttachmentIds = [...alreadyUploadedIds, ...uploadedIds];
|
|
38515
|
-
// Call the original send message with attachment IDs
|
|
38516
|
-
props.handleSendMessage(allAttachmentIds);
|
|
38517
|
-
// Clear selected files and revoke URLs
|
|
38518
|
-
selectedFiles.forEach(f => URL.revokeObjectURL(f.previewUrl));
|
|
38519
|
-
setSelectedFiles([]);
|
|
38520
|
-
}), [selectedFiles, props, i18n.language]);
|
|
38526
|
+
}), [selectedFiles, props, i18n.language, isSending]);
|
|
38521
38527
|
// Check if any files are currently uploading
|
|
38522
38528
|
var hasUploadingFiles = selectedFiles.some(f => f.uploading);
|
|
38523
38529
|
// Check if there are files with errors
|
|
38524
38530
|
var hasFileErrors = selectedFiles.some(f => f.error !== null);
|
|
38525
38531
|
// Allow sending if there's text OR files selected (files will be uploaded on send)
|
|
38526
38532
|
var hasContentToSend = props.inputMessage.trim() !== '' || selectedFiles.length > 0;
|
|
38527
|
-
var isSendDisabled = props.isLoading || !hasContentToSend || hasUploadingFiles || hasFileErrors;
|
|
38533
|
+
var isSendDisabled = props.isLoading || isSending || !hasContentToSend || hasUploadingFiles || hasFileErrors;
|
|
38534
|
+
var showLoading = props.isLoading || isSending || hasUploadingFiles;
|
|
38528
38535
|
var handleKeyDown = React.useCallback(e => {
|
|
38529
38536
|
if (e.key === 'Enter' && !e.shiftKey) {
|
|
38530
38537
|
e.preventDefault();
|
|
@@ -38598,10 +38605,12 @@ var ChatWindowFooter = props => {
|
|
|
38598
38605
|
size: 'icon',
|
|
38599
38606
|
onClick: handleSendMessageWithAttachments,
|
|
38600
38607
|
disabled: isSendDisabled,
|
|
38601
|
-
className: 'babylai-rounded-full babylai-bg-primary-500 babylai-hover:babylai-bg-purple-600 babylai-w-8 babylai-h-8 disabled:babylai-opacity-50',
|
|
38608
|
+
className: 'babylai-rounded-full babylai-bg-primary-500 babylai-hover:babylai-bg-purple-600 babylai-w-8 babylai-h-8 !babylai-p-0 babylai-flex babylai-items-center babylai-justify-center disabled:babylai-opacity-50',
|
|
38602
38609
|
type: 'button',
|
|
38603
|
-
children: jsxRuntime.jsx(
|
|
38604
|
-
className:
|
|
38610
|
+
children: showLoading ? jsxRuntime.jsx("div", {
|
|
38611
|
+
className: 'babylai-inline-block babylai-animate-spin babylai-rounded-full babylai-h-4 babylai-w-4 babylai-aspect-square babylai-border-2 babylai-border-white babylai-border-t-transparent babylai-box-border'
|
|
38612
|
+
}) : jsxRuntime.jsx(EnvelopeIcon, {
|
|
38613
|
+
className: "babylai-w-4 babylai-h-4 babylai-flex-shrink-0 ".concat(dir === 'rtl' ? 'babylai-rotate-270' : '')
|
|
38605
38614
|
})
|
|
38606
38615
|
})]
|
|
38607
38616
|
}), previewImage && jsxRuntime.jsx(ImagePreviewDialog, {
|
|
@@ -38690,7 +38699,7 @@ var MessageComponent = /*#__PURE__*/React__default["default"].memo(_ref => {
|
|
|
38690
38699
|
var textDirection = message.senderType === 1 ? 'babylai-justify-end' : 'babylai-justify-start';
|
|
38691
38700
|
var handleImageClick = React.useCallback(clickedIndex => {
|
|
38692
38701
|
// Use attachmentUrls if available (from Ably), otherwise use attachmentIds (user-sent)
|
|
38693
|
-
var attachments = message.attachmentUrls ||
|
|
38702
|
+
var attachments = message.attachmentUrls || [];
|
|
38694
38703
|
if (attachments.length > 0) {
|
|
38695
38704
|
onImageClick(attachments, clickedIndex);
|
|
38696
38705
|
}
|