@aslaluroba/help-center-react 3.2.1 → 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/components/ui/image-attachment.d.ts +2 -1
- package/dist/index.css +1 -1
- package/dist/index.esm.js +352 -173
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +352 -173
- package/dist/index.js.map +1 -1
- package/dist/lib/types.d.ts +1 -0
- package/dist/services.esm.js +71 -14
- package/dist/services.esm.js.map +1 -1
- package/dist/services.js +71 -14
- package/dist/services.js.map +1 -1
- package/dist/ui/chatbot-popup/chat-window-screen/footer.d.ts +1 -0
- package/dist/ui/chatbot-popup/chat-window-screen/index.d.ts +2 -1
- package/package.json +1 -1
- package/src/components/ui/agent-response/agent-response.tsx +5 -3
- package/src/components/ui/image-attachment.tsx +29 -17
- package/src/components/ui/image-preview-dialog.tsx +46 -0
- package/src/core/AblyService.ts +59 -12
- package/src/core/api.ts +0 -1
- package/src/lib/custom-hooks/useTypewriter.ts +5 -3
- package/src/lib/types.ts +2 -1
- package/src/ui/chatbot-popup/chat-window-screen/footer.tsx +133 -95
- package/src/ui/chatbot-popup/chat-window-screen/index.tsx +69 -18
- package/src/ui/help-center.tsx +13 -8
- package/src/ui/help-popup.tsx +3 -1
package/dist/index.esm.js
CHANGED
|
@@ -16245,10 +16245,19 @@ class ClientAblyService {
|
|
|
16245
16245
|
token: ablyToken,
|
|
16246
16246
|
autoConnect: true
|
|
16247
16247
|
});
|
|
16248
|
+
_this.client.connection.on('failed', stateChange => {
|
|
16249
|
+
var _a;
|
|
16250
|
+
console.error('[AblyService] Connection state: failed', {
|
|
16251
|
+
reason: (_a = stateChange.reason) === null || _a === void 0 ? void 0 : _a.message,
|
|
16252
|
+
error: stateChange.reason
|
|
16253
|
+
});
|
|
16254
|
+
});
|
|
16248
16255
|
// Wait for connection to be established
|
|
16249
16256
|
yield new Promise((resolve, reject) => {
|
|
16250
16257
|
if (!_this.client) {
|
|
16251
|
-
|
|
16258
|
+
var error = new Error('Failed to initialize Ably client');
|
|
16259
|
+
console.error('[AblyService]', error);
|
|
16260
|
+
reject(error);
|
|
16252
16261
|
return;
|
|
16253
16262
|
}
|
|
16254
16263
|
_this.client.connection.once('connected', () => {
|
|
@@ -16257,23 +16266,38 @@ class ClientAblyService {
|
|
|
16257
16266
|
resolve();
|
|
16258
16267
|
});
|
|
16259
16268
|
_this.client.connection.once('failed', stateChange => {
|
|
16260
|
-
var _a;
|
|
16261
|
-
|
|
16269
|
+
var _a, _b;
|
|
16270
|
+
var error = new Error("Ably connection failed: ".concat(((_a = stateChange.reason) === null || _a === void 0 ? void 0 : _a.message) || 'Unknown error'));
|
|
16271
|
+
console.error('[AblyService] Connection failed', {
|
|
16272
|
+
reason: (_b = stateChange.reason) === null || _b === void 0 ? void 0 : _b.message,
|
|
16273
|
+
error: stateChange.reason
|
|
16274
|
+
});
|
|
16275
|
+
reject(error);
|
|
16262
16276
|
});
|
|
16263
16277
|
_this.client.connection.once('disconnected', stateChange => {
|
|
16264
|
-
var _a;
|
|
16265
|
-
|
|
16278
|
+
var _a, _b;
|
|
16279
|
+
var error = new Error("Ably connection disconnected: ".concat(((_a = stateChange.reason) === null || _a === void 0 ? void 0 : _a.message) || 'Unknown error'));
|
|
16280
|
+
console.error('[AblyService] Connection disconnected', {
|
|
16281
|
+
reason: (_b = stateChange.reason) === null || _b === void 0 ? void 0 : _b.message
|
|
16282
|
+
});
|
|
16283
|
+
reject(error);
|
|
16266
16284
|
});
|
|
16267
16285
|
// Set a timeout for connection
|
|
16268
16286
|
setTimeout(() => {
|
|
16269
16287
|
if (!_this.isConnected) {
|
|
16270
|
-
|
|
16288
|
+
var _error = new Error('Ably connection timeout');
|
|
16289
|
+
console.error('[AblyService] Connection timeout after 10 seconds');
|
|
16290
|
+
reject(_error);
|
|
16271
16291
|
}
|
|
16272
16292
|
}, 10000);
|
|
16273
16293
|
});
|
|
16274
16294
|
// Subscribe to the session room
|
|
16275
16295
|
yield _this.joinChannel(sessionId, onMessageReceived, tenantId);
|
|
16276
16296
|
} catch (error) {
|
|
16297
|
+
console.error('[AblyService] Error in startConnection', {
|
|
16298
|
+
error,
|
|
16299
|
+
sessionId
|
|
16300
|
+
});
|
|
16277
16301
|
_this.isConnected = false;
|
|
16278
16302
|
_this.sessionId = null;
|
|
16279
16303
|
throw error;
|
|
@@ -16284,23 +16308,53 @@ class ClientAblyService {
|
|
|
16284
16308
|
var _this2 = this;
|
|
16285
16309
|
return _asyncToGenerator(function* () {
|
|
16286
16310
|
if (!_this2.client) {
|
|
16287
|
-
|
|
16311
|
+
var error = new Error('Chat client not initialized');
|
|
16312
|
+
console.error('[AblyService] joinChannel error:', error);
|
|
16313
|
+
throw error;
|
|
16288
16314
|
}
|
|
16289
16315
|
var roomName = "session:".concat(tenantId, ":").concat(sessionId);
|
|
16290
16316
|
// Set up raw channel subscription for server messages
|
|
16291
16317
|
if (_this2.client) {
|
|
16292
16318
|
_this2.channel = _this2.client.channels.get(roomName);
|
|
16319
|
+
_this2.channel.on('failed', stateChange => {
|
|
16320
|
+
var _a;
|
|
16321
|
+
console.error('[AblyService] Channel failed', {
|
|
16322
|
+
roomName,
|
|
16323
|
+
reason: (_a = stateChange.reason) === null || _a === void 0 ? void 0 : _a.message,
|
|
16324
|
+
error: stateChange.reason
|
|
16325
|
+
});
|
|
16326
|
+
});
|
|
16293
16327
|
// Subscribe to assistant/system responses
|
|
16294
16328
|
_this2.channel.subscribe('ReceiveMessage', message => {
|
|
16295
|
-
var _a, _b, _c, _d, _e, _f;
|
|
16329
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
16296
16330
|
try {
|
|
16297
|
-
|
|
16298
|
-
var
|
|
16299
|
-
var
|
|
16300
|
-
var
|
|
16301
|
-
|
|
16331
|
+
// Ensure messageContent is always a string (default to empty string if undefined)
|
|
16332
|
+
var messageContent = typeof message.data === 'string' ? message.data : (_d = (_b = (_a = message.data) === null || _a === void 0 ? void 0 : _a.content) !== null && _b !== void 0 ? _b : (_c = message.data) === null || _c === void 0 ? void 0 : _c.message) !== null && _d !== void 0 ? _d : '';
|
|
16333
|
+
var senderType = ((_e = message.data) === null || _e === void 0 ? void 0 : _e.senderType) || 3; // Assistant
|
|
16334
|
+
var needsAgent = ((_f = message.data) === null || _f === void 0 ? void 0 : _f.needsAgent) || ((_g = message.data) === null || _g === void 0 ? void 0 : _g.actionType) == 'needs_agent' || false;
|
|
16335
|
+
var attachments = ((_h = message.data) === null || _h === void 0 ? void 0 : _h.attachments) || [];
|
|
16336
|
+
// Extract downloadUrl from attachments (Ably now returns downloadUrl directly)
|
|
16337
|
+
// Attachments can be: strings (URLs), objects with downloadUrl, or objects with id
|
|
16338
|
+
var attachmentUrls = attachments.map(attachment => {
|
|
16339
|
+
if (typeof attachment === 'string') {
|
|
16340
|
+
// If it's already a string, it's a URL
|
|
16341
|
+
return attachment;
|
|
16342
|
+
} else if (attachment === null || attachment === void 0 ? void 0 : attachment.downloadUrl) {
|
|
16343
|
+
// If it's an object with downloadUrl, use that
|
|
16344
|
+
return attachment.downloadUrl;
|
|
16345
|
+
} else if (attachment === null || attachment === void 0 ? void 0 : attachment.url) {
|
|
16346
|
+
// Fallback to url property
|
|
16347
|
+
return attachment.url;
|
|
16348
|
+
}
|
|
16349
|
+
// If it's an object with id, we'll need to keep it for backward compatibility
|
|
16350
|
+
return null;
|
|
16351
|
+
}).filter(url => url !== null);
|
|
16352
|
+
onMessageReceived(messageContent, senderType, needsAgent, attachmentUrls);
|
|
16302
16353
|
} catch (error) {
|
|
16303
|
-
|
|
16354
|
+
console.error('[AblyService] Error processing message', {
|
|
16355
|
+
error,
|
|
16356
|
+
message
|
|
16357
|
+
});
|
|
16304
16358
|
}
|
|
16305
16359
|
});
|
|
16306
16360
|
yield _this2.channel.attach();
|
|
@@ -16330,6 +16384,9 @@ class ClientAblyService {
|
|
|
16330
16384
|
_this3.isConnected = false;
|
|
16331
16385
|
_this3.sessionId = null;
|
|
16332
16386
|
} catch (error) {
|
|
16387
|
+
console.error('[AblyService] Error in stopConnection', {
|
|
16388
|
+
error
|
|
16389
|
+
});
|
|
16333
16390
|
// Reset state even if there's an error
|
|
16334
16391
|
_this3.isConnected = false;
|
|
16335
16392
|
_this3.sessionId = null;
|
|
@@ -16482,19 +16539,21 @@ function useTypewriter(text) {
|
|
|
16482
16539
|
var onType = arguments.length > 2 ? arguments[2] : undefined;
|
|
16483
16540
|
var [displayedText, setDisplayedText] = useState('');
|
|
16484
16541
|
useEffect(() => {
|
|
16542
|
+
// Ensure text is always a string to prevent errors
|
|
16543
|
+
var safeText = text !== null && text !== void 0 ? text : '';
|
|
16485
16544
|
var index = 0;
|
|
16486
16545
|
setDisplayedText('');
|
|
16487
16546
|
var interval = setInterval(() => {
|
|
16488
16547
|
setDisplayedText(() => {
|
|
16489
|
-
var next =
|
|
16548
|
+
var next = safeText.slice(0, index + 1);
|
|
16490
16549
|
index++;
|
|
16491
16550
|
if (onType) onType();
|
|
16492
|
-
if (index >=
|
|
16551
|
+
if (index >= safeText.length) clearInterval(interval);
|
|
16493
16552
|
return next;
|
|
16494
16553
|
});
|
|
16495
16554
|
}, speed);
|
|
16496
16555
|
return () => clearInterval(interval);
|
|
16497
|
-
}, [text]);
|
|
16556
|
+
}, [text, onType]);
|
|
16498
16557
|
return displayedText;
|
|
16499
16558
|
}
|
|
16500
16559
|
|
|
@@ -34281,11 +34340,13 @@ var AgentResponse = _ref => {
|
|
|
34281
34340
|
messageId,
|
|
34282
34341
|
onType
|
|
34283
34342
|
} = _ref;
|
|
34343
|
+
// Ensure messageContent is always a string to prevent errors
|
|
34344
|
+
var safeMessageContent = messageContent !== null && messageContent !== void 0 ? messageContent : '';
|
|
34284
34345
|
var shouldAnimate = (senderType === 2 || senderType === 3) && !seenMessagesRef.has(messageId);
|
|
34285
|
-
var animatedText = useTypewriter(
|
|
34286
|
-
var finalMessage = shouldAnimate ? animatedText :
|
|
34346
|
+
var animatedText = useTypewriter(safeMessageContent, 20, onType);
|
|
34347
|
+
var finalMessage = shouldAnimate ? animatedText : safeMessageContent;
|
|
34287
34348
|
// Mark message as "seen" after full animation
|
|
34288
|
-
if (shouldAnimate && finalMessage ===
|
|
34349
|
+
if (shouldAnimate && finalMessage === safeMessageContent) {
|
|
34289
34350
|
seenMessagesRef.add(messageId);
|
|
34290
34351
|
}
|
|
34291
34352
|
return jsx("div", {
|
|
@@ -34435,6 +34496,32 @@ var ImagePreviewDialog = _ref => {
|
|
|
34435
34496
|
y: 0
|
|
34436
34497
|
});
|
|
34437
34498
|
}, []);
|
|
34499
|
+
var handleDownload = useCallback(/*#__PURE__*/_asyncToGenerator(function* () {
|
|
34500
|
+
if (!currentImageUrl) return;
|
|
34501
|
+
try {
|
|
34502
|
+
// Fetch the image as a blob
|
|
34503
|
+
var response = yield fetch(currentImageUrl);
|
|
34504
|
+
var blob = yield response.blob();
|
|
34505
|
+
// Create a temporary URL for the blob
|
|
34506
|
+
var blobUrl = URL.createObjectURL(blob);
|
|
34507
|
+
// Extract filename from URL or use a default
|
|
34508
|
+
var urlParts = currentImageUrl.split('/');
|
|
34509
|
+
var filename = urlParts[urlParts.length - 1].split('?')[0] || 'image.png';
|
|
34510
|
+
// Create a temporary anchor element and trigger download
|
|
34511
|
+
var link = document.createElement('a');
|
|
34512
|
+
link.href = blobUrl;
|
|
34513
|
+
link.download = filename;
|
|
34514
|
+
document.body.appendChild(link);
|
|
34515
|
+
link.click();
|
|
34516
|
+
// Cleanup
|
|
34517
|
+
document.body.removeChild(link);
|
|
34518
|
+
URL.revokeObjectURL(blobUrl);
|
|
34519
|
+
} catch (error) {
|
|
34520
|
+
console.error('Failed to download image:', error);
|
|
34521
|
+
// Fallback: open in new tab if download fails
|
|
34522
|
+
window.open(currentImageUrl, '_blank');
|
|
34523
|
+
}
|
|
34524
|
+
}), [currentImageUrl]);
|
|
34438
34525
|
var handleClose = useCallback(() => {
|
|
34439
34526
|
setZoomLevel(1);
|
|
34440
34527
|
setImagePosition({
|
|
@@ -34635,6 +34722,27 @@ var ImagePreviewDialog = _ref => {
|
|
|
34635
34722
|
"aria-label": 'Reset zoom',
|
|
34636
34723
|
type: 'button',
|
|
34637
34724
|
children: "Reset"
|
|
34725
|
+
}), jsx("div", {
|
|
34726
|
+
className: 'babylai-h-9 babylai-w-px babylai-bg-white/20 babylai-mx-1'
|
|
34727
|
+
}), jsx(Button, {
|
|
34728
|
+
variant: 'ghost',
|
|
34729
|
+
size: 'icon',
|
|
34730
|
+
onClick: handleDownload,
|
|
34731
|
+
className: 'babylai-text-white hover:babylai-text-white/80 hover:babylai-bg-white/10 babylai-h-9 babylai-w-9',
|
|
34732
|
+
"aria-label": 'Download image',
|
|
34733
|
+
type: 'button',
|
|
34734
|
+
children: jsx("svg", {
|
|
34735
|
+
className: 'babylai-w-5 babylai-h-5',
|
|
34736
|
+
fill: 'none',
|
|
34737
|
+
stroke: 'currentColor',
|
|
34738
|
+
viewBox: '0 0 24 24',
|
|
34739
|
+
children: jsx("path", {
|
|
34740
|
+
strokeLinecap: 'round',
|
|
34741
|
+
strokeLinejoin: 'round',
|
|
34742
|
+
strokeWidth: 2,
|
|
34743
|
+
d: 'M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4'
|
|
34744
|
+
})
|
|
34745
|
+
})
|
|
34638
34746
|
})]
|
|
34639
34747
|
}), hasMultipleImages && jsx("div", {
|
|
34640
34748
|
className: cn('babylai-absolute babylai-top-4 babylai-z-[60]', 'babylai-bg-black/50 babylai-backdrop-blur-sm babylai-rounded-lg babylai-px-4 babylai-py-2', dir === 'rtl' ? 'babylai-right-1/2 babylai-translate-x-1/2' : 'babylai-left-1/2 -babylai-translate-x-1/2'),
|
|
@@ -34668,6 +34776,7 @@ ImagePreviewDialog.displayName = 'ImagePreviewDialog';
|
|
|
34668
34776
|
var ImageAttachment = _ref => {
|
|
34669
34777
|
var {
|
|
34670
34778
|
fileId,
|
|
34779
|
+
imageUrl: propImageUrl,
|
|
34671
34780
|
className,
|
|
34672
34781
|
enablePreview = true,
|
|
34673
34782
|
onClick
|
|
@@ -34675,30 +34784,39 @@ var ImageAttachment = _ref => {
|
|
|
34675
34784
|
var {
|
|
34676
34785
|
i18n
|
|
34677
34786
|
} = useLocalTranslation();
|
|
34678
|
-
var [imageUrl, setImageUrl] = useState(null);
|
|
34679
|
-
var [loading, setLoading] = useState(
|
|
34787
|
+
var [imageUrl, setImageUrl] = useState(propImageUrl || null);
|
|
34788
|
+
var [loading, setLoading] = useState(!propImageUrl && !!fileId);
|
|
34680
34789
|
var [error, setError] = useState(false);
|
|
34681
34790
|
var [isPreviewOpen, setIsPreviewOpen] = useState(false);
|
|
34682
34791
|
useEffect(() => {
|
|
34683
|
-
|
|
34684
|
-
|
|
34685
|
-
|
|
34686
|
-
|
|
34687
|
-
|
|
34688
|
-
|
|
34689
|
-
|
|
34690
|
-
|
|
34691
|
-
|
|
34692
|
-
|
|
34693
|
-
|
|
34694
|
-
|
|
34695
|
-
|
|
34696
|
-
|
|
34697
|
-
|
|
34698
|
-
|
|
34699
|
-
|
|
34700
|
-
|
|
34701
|
-
|
|
34792
|
+
// If we have a direct URL, use it immediately
|
|
34793
|
+
if (propImageUrl) {
|
|
34794
|
+
setImageUrl(propImageUrl);
|
|
34795
|
+
setLoading(false);
|
|
34796
|
+
return;
|
|
34797
|
+
}
|
|
34798
|
+
// If we only have a fileId, fetch the URL using presignDownload
|
|
34799
|
+
if (fileId) {
|
|
34800
|
+
var fetchImageUrl = /*#__PURE__*/function () {
|
|
34801
|
+
var _ref2 = _asyncToGenerator(function* () {
|
|
34802
|
+
try {
|
|
34803
|
+
setLoading(true);
|
|
34804
|
+
setError(false);
|
|
34805
|
+
var response = yield presignDownload(fileId, i18n.language);
|
|
34806
|
+
setImageUrl(response.downloadUrl);
|
|
34807
|
+
} catch (err) {
|
|
34808
|
+
setError(true);
|
|
34809
|
+
} finally {
|
|
34810
|
+
setLoading(false);
|
|
34811
|
+
}
|
|
34812
|
+
});
|
|
34813
|
+
return function fetchImageUrl() {
|
|
34814
|
+
return _ref2.apply(this, arguments);
|
|
34815
|
+
};
|
|
34816
|
+
}();
|
|
34817
|
+
fetchImageUrl();
|
|
34818
|
+
}
|
|
34819
|
+
}, [fileId, propImageUrl, i18n.language]);
|
|
34702
34820
|
var handleImageClick = () => {
|
|
34703
34821
|
if (onClick) {
|
|
34704
34822
|
onClick();
|
|
@@ -38246,95 +38364,31 @@ var ChatWindowFooter = props => {
|
|
|
38246
38364
|
var fileInputRef = useRef(null);
|
|
38247
38365
|
var [selectedFiles, setSelectedFiles] = useState([]);
|
|
38248
38366
|
var [previewImage, setPreviewImage] = useState(null);
|
|
38367
|
+
var [isSending, setIsSending] = useState(false);
|
|
38249
38368
|
var handleAttachClick = useCallback(() => {
|
|
38250
38369
|
var _a;
|
|
38251
38370
|
(_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
38252
38371
|
}, []);
|
|
38253
|
-
var handleFileSelect = useCallback(
|
|
38254
|
-
var
|
|
38255
|
-
|
|
38256
|
-
|
|
38257
|
-
|
|
38258
|
-
|
|
38259
|
-
|
|
38260
|
-
|
|
38261
|
-
|
|
38262
|
-
|
|
38263
|
-
|
|
38264
|
-
|
|
38265
|
-
|
|
38266
|
-
|
|
38267
|
-
|
|
38268
|
-
|
|
38269
|
-
|
|
38270
|
-
|
|
38271
|
-
|
|
38272
|
-
|
|
38273
|
-
yield handleUploadFiles(newFiles);
|
|
38274
|
-
});
|
|
38275
|
-
return function (_x) {
|
|
38276
|
-
return _ref.apply(this, arguments);
|
|
38277
|
-
};
|
|
38278
|
-
}(), []);
|
|
38279
|
-
var handleUploadFiles = useCallback(/*#__PURE__*/function () {
|
|
38280
|
-
var _ref2 = _asyncToGenerator(function* (filesToUpload) {
|
|
38281
|
-
// Get session ID
|
|
38282
|
-
var sessionId;
|
|
38283
|
-
try {
|
|
38284
|
-
sessionId = yield props.onEnsureSession();
|
|
38285
|
-
} catch (error) {
|
|
38286
|
-
// Mark all files as error
|
|
38287
|
-
setSelectedFiles(prev => prev.map(f => filesToUpload.some(ftl => ftl.previewUrl === f.previewUrl) ? _objectSpread2(_objectSpread2({}, f), {}, {
|
|
38288
|
-
error: 'Failed to initialize session',
|
|
38289
|
-
uploading: false
|
|
38290
|
-
}) : f));
|
|
38291
|
-
return;
|
|
38292
|
-
}
|
|
38293
|
-
// Upload each file
|
|
38294
|
-
var _loop = function* _loop(fileDto) {
|
|
38295
|
-
try {
|
|
38296
|
-
// Mark as uploading
|
|
38297
|
-
setSelectedFiles(prev => prev.map(f => f.previewUrl === fileDto.previewUrl ? _objectSpread2(_objectSpread2({}, f), {}, {
|
|
38298
|
-
uploading: true,
|
|
38299
|
-
error: null
|
|
38300
|
-
}) : f));
|
|
38301
|
-
// Get presigned URL
|
|
38302
|
-
var presignResponse = yield presignUpload(sessionId, fileDto.file, i18n.language);
|
|
38303
|
-
// Upload file to presigned URL using axios
|
|
38304
|
-
// Important: Content-Type must match the file type (e.g., 'image/png'), not 'multipart/form-data'
|
|
38305
|
-
var uploadResponse = yield axios$1.put(presignResponse.uploadUrl, fileDto.file, {
|
|
38306
|
-
headers: {
|
|
38307
|
-
'Content-Type': fileDto.file.type
|
|
38308
|
-
},
|
|
38309
|
-
onUploadProgress: () => {
|
|
38310
|
-
// Upload progress tracking (silent)
|
|
38311
|
-
}
|
|
38312
|
-
});
|
|
38313
|
-
if (uploadResponse.status !== 200 && uploadResponse.status !== 204) {
|
|
38314
|
-
throw new Error("Upload failed with status ".concat(uploadResponse.status));
|
|
38315
|
-
}
|
|
38316
|
-
// Update with uploaded ID
|
|
38317
|
-
setSelectedFiles(prev => prev.map(f => f.previewUrl === fileDto.previewUrl ? _objectSpread2(_objectSpread2({}, f), {}, {
|
|
38318
|
-
uploading: false,
|
|
38319
|
-
uploadedId: presignResponse.id,
|
|
38320
|
-
error: null
|
|
38321
|
-
}) : f));
|
|
38322
|
-
} catch (error) {
|
|
38323
|
-
setSelectedFiles(prev => prev.map(f => f.previewUrl === fileDto.previewUrl ? _objectSpread2(_objectSpread2({}, f), {}, {
|
|
38324
|
-
uploading: false,
|
|
38325
|
-
error: 'Upload failed',
|
|
38326
|
-
uploadedId: null
|
|
38327
|
-
}) : f));
|
|
38328
|
-
}
|
|
38329
|
-
};
|
|
38330
|
-
for (var fileDto of filesToUpload) {
|
|
38331
|
-
yield* _loop(fileDto);
|
|
38332
|
-
}
|
|
38333
|
-
});
|
|
38334
|
-
return function (_x2) {
|
|
38335
|
-
return _ref2.apply(this, arguments);
|
|
38336
|
-
};
|
|
38337
|
-
}(), [props.onEnsureSession, i18n.language]);
|
|
38372
|
+
var handleFileSelect = useCallback(e => {
|
|
38373
|
+
var files = Array.from(e.target.files || []);
|
|
38374
|
+
// Validate that all files are images
|
|
38375
|
+
var imageFiles = files.filter(file => file.type.startsWith('image/'));
|
|
38376
|
+
// Create preview URLs and add to selected files (don't upload yet)
|
|
38377
|
+
var newFiles = imageFiles.map(file => ({
|
|
38378
|
+
file,
|
|
38379
|
+
previewUrl: URL.createObjectURL(file),
|
|
38380
|
+
uploading: false,
|
|
38381
|
+
uploadedId: null,
|
|
38382
|
+
error: null
|
|
38383
|
+
}));
|
|
38384
|
+
setSelectedFiles(prev => [...prev, ...newFiles]);
|
|
38385
|
+
// Clear the input
|
|
38386
|
+
if (fileInputRef.current) {
|
|
38387
|
+
fileInputRef.current.value = '';
|
|
38388
|
+
}
|
|
38389
|
+
// Don't upload files immediately - wait for send button click
|
|
38390
|
+
}, []);
|
|
38391
|
+
// Removed handleUploadFiles - files are now uploaded in handleSendMessageWithAttachments
|
|
38338
38392
|
var handleRemoveFile = useCallback(previewUrl => {
|
|
38339
38393
|
setSelectedFiles(prev => {
|
|
38340
38394
|
var fileToRemove = prev.find(f => f.previewUrl === previewUrl);
|
|
@@ -38344,29 +38398,114 @@ var ChatWindowFooter = props => {
|
|
|
38344
38398
|
return prev.filter(f => f.previewUrl !== previewUrl);
|
|
38345
38399
|
});
|
|
38346
38400
|
}, []);
|
|
38347
|
-
var handleSendMessageWithAttachments = useCallback(()
|
|
38348
|
-
//
|
|
38349
|
-
|
|
38350
|
-
|
|
38351
|
-
|
|
38352
|
-
|
|
38353
|
-
|
|
38354
|
-
|
|
38355
|
-
|
|
38356
|
-
|
|
38357
|
-
|
|
38358
|
-
|
|
38359
|
-
|
|
38360
|
-
|
|
38401
|
+
var handleSendMessageWithAttachments = useCallback(/*#__PURE__*/_asyncToGenerator(function* () {
|
|
38402
|
+
// Prevent sending if already loading
|
|
38403
|
+
if (props.isLoading || isSending) {
|
|
38404
|
+
return;
|
|
38405
|
+
}
|
|
38406
|
+
setIsSending(true);
|
|
38407
|
+
try {
|
|
38408
|
+
// Get files that need to be uploaded (those without uploadedId)
|
|
38409
|
+
var filesToUpload = selectedFiles.filter(f => f.uploadedId === null && !f.error);
|
|
38410
|
+
var alreadyUploadedIds = selectedFiles.filter(f => f.uploadedId !== null).map(f => f.uploadedId);
|
|
38411
|
+
// Declare uploadedIds outside the if block so it's accessible later
|
|
38412
|
+
var uploadedIds = [];
|
|
38413
|
+
// If there are files to upload, upload them first
|
|
38414
|
+
if (filesToUpload.length > 0) {
|
|
38415
|
+
// Get session ID - ensure session exists if needed (for image-only messages)
|
|
38416
|
+
var sessionId = null;
|
|
38417
|
+
try {
|
|
38418
|
+
// Use existing sessionId if available, otherwise ensure session is created
|
|
38419
|
+
if (props.sessionId) {
|
|
38420
|
+
sessionId = props.sessionId;
|
|
38421
|
+
} else {
|
|
38422
|
+
// Ensure session exists before uploading files (allows starting chat with image only)
|
|
38423
|
+
sessionId = yield props.onEnsureSession();
|
|
38424
|
+
}
|
|
38425
|
+
} catch (error) {
|
|
38426
|
+
console.error('[ChatWindowFooter] Failed to get sessionId for file upload:', error);
|
|
38427
|
+
// Mark all files as error
|
|
38428
|
+
setSelectedFiles(prev => prev.map(f => filesToUpload.some(ftl => ftl.previewUrl === f.previewUrl) ? _objectSpread2(_objectSpread2({}, f), {}, {
|
|
38429
|
+
error: 'Failed to initialize session',
|
|
38430
|
+
uploading: false
|
|
38431
|
+
}) : f));
|
|
38432
|
+
setIsSending(false);
|
|
38433
|
+
return;
|
|
38434
|
+
}
|
|
38435
|
+
// Upload each file and collect uploaded IDs
|
|
38436
|
+
uploadedIds = [];
|
|
38437
|
+
var hasUploadErrors = false;
|
|
38438
|
+
var _loop = function* _loop(fileDto) {
|
|
38439
|
+
try {
|
|
38440
|
+
// Mark as uploading
|
|
38441
|
+
setSelectedFiles(prev => prev.map(f => f.previewUrl === fileDto.previewUrl ? _objectSpread2(_objectSpread2({}, f), {}, {
|
|
38442
|
+
uploading: true,
|
|
38443
|
+
error: null
|
|
38444
|
+
}) : f));
|
|
38445
|
+
// Get presigned URL
|
|
38446
|
+
var presignResponse = yield presignUpload(sessionId, fileDto.file, i18n.language);
|
|
38447
|
+
// Upload file to presigned URL using axios
|
|
38448
|
+
var uploadResponse = yield axios$1.put(presignResponse.uploadUrl, fileDto.file, {
|
|
38449
|
+
headers: {
|
|
38450
|
+
'Content-Type': fileDto.file.type
|
|
38451
|
+
},
|
|
38452
|
+
onUploadProgress: () => {
|
|
38453
|
+
// Upload progress tracking (silent)
|
|
38454
|
+
}
|
|
38455
|
+
});
|
|
38456
|
+
if (uploadResponse.status !== 200 && uploadResponse.status !== 204) {
|
|
38457
|
+
throw new Error("Upload failed with status ".concat(uploadResponse.status));
|
|
38458
|
+
}
|
|
38459
|
+
// Collect uploaded ID
|
|
38460
|
+
uploadedIds.push(presignResponse.id);
|
|
38461
|
+
// Update with uploaded ID
|
|
38462
|
+
setSelectedFiles(prev => prev.map(f => f.previewUrl === fileDto.previewUrl ? _objectSpread2(_objectSpread2({}, f), {}, {
|
|
38463
|
+
uploading: false,
|
|
38464
|
+
uploadedId: presignResponse.id,
|
|
38465
|
+
error: null
|
|
38466
|
+
}) : f));
|
|
38467
|
+
} catch (error) {
|
|
38468
|
+
console.error('[ChatWindowFooter] File upload failed:', error);
|
|
38469
|
+
hasUploadErrors = true;
|
|
38470
|
+
setSelectedFiles(prev => prev.map(f => f.previewUrl === fileDto.previewUrl ? _objectSpread2(_objectSpread2({}, f), {}, {
|
|
38471
|
+
uploading: false,
|
|
38472
|
+
error: 'Upload failed',
|
|
38473
|
+
uploadedId: null
|
|
38474
|
+
}) : f));
|
|
38475
|
+
}
|
|
38476
|
+
};
|
|
38477
|
+
for (var fileDto of filesToUpload) {
|
|
38478
|
+
yield* _loop(fileDto);
|
|
38479
|
+
}
|
|
38480
|
+
// If any uploads failed, don't send the message
|
|
38481
|
+
if (hasUploadErrors) {
|
|
38482
|
+
console.error('[ChatWindowFooter] Some files failed to upload, not sending message');
|
|
38483
|
+
setIsSending(false);
|
|
38484
|
+
return;
|
|
38485
|
+
}
|
|
38486
|
+
}
|
|
38487
|
+
// Get all successfully uploaded file IDs (already uploaded + newly uploaded)
|
|
38488
|
+
// Use uploadedIds from the upload loop instead of reading from state
|
|
38489
|
+
var allAttachmentIds = [...alreadyUploadedIds, ...uploadedIds];
|
|
38490
|
+
// Call the original send message with attachment IDs
|
|
38491
|
+
props.handleSendMessage(allAttachmentIds);
|
|
38492
|
+
// Clear selected files and revoke URLs
|
|
38493
|
+
selectedFiles.forEach(f => URL.revokeObjectURL(f.previewUrl));
|
|
38494
|
+
setSelectedFiles([]);
|
|
38495
|
+
setIsSending(false);
|
|
38496
|
+
} catch (error) {
|
|
38497
|
+
console.error('[ChatWindowFooter] Error sending message:', error);
|
|
38498
|
+
setIsSending(false);
|
|
38499
|
+
}
|
|
38500
|
+
}), [selectedFiles, props, i18n.language, isSending]);
|
|
38361
38501
|
// Check if any files are currently uploading
|
|
38362
38502
|
var hasUploadingFiles = selectedFiles.some(f => f.uploading);
|
|
38363
|
-
// Check if there are files
|
|
38364
|
-
|
|
38365
|
-
|
|
38366
|
-
|
|
38367
|
-
var
|
|
38368
|
-
var
|
|
38369
|
-
var isSendDisabled = props.isLoading || props.inputMessage.trim() === '' || hasUploadingFiles || hasPendingFiles || allFilesHaveErrors;
|
|
38503
|
+
// Check if there are files with errors
|
|
38504
|
+
var hasFileErrors = selectedFiles.some(f => f.error !== null);
|
|
38505
|
+
// Allow sending if there's text OR files selected (files will be uploaded on send)
|
|
38506
|
+
var hasContentToSend = props.inputMessage.trim() !== '' || selectedFiles.length > 0;
|
|
38507
|
+
var isSendDisabled = props.isLoading || isSending || !hasContentToSend || hasUploadingFiles || hasFileErrors;
|
|
38508
|
+
var showLoading = props.isLoading || isSending || hasUploadingFiles;
|
|
38370
38509
|
var handleKeyDown = useCallback(e => {
|
|
38371
38510
|
if (e.key === 'Enter' && !e.shiftKey) {
|
|
38372
38511
|
e.preventDefault();
|
|
@@ -38440,10 +38579,12 @@ var ChatWindowFooter = props => {
|
|
|
38440
38579
|
size: 'icon',
|
|
38441
38580
|
onClick: handleSendMessageWithAttachments,
|
|
38442
38581
|
disabled: isSendDisabled,
|
|
38443
|
-
className: 'babylai-rounded-full babylai-bg-primary-500 babylai-hover:babylai-bg-purple-600 babylai-w-8 babylai-h-8 disabled:babylai-opacity-50',
|
|
38582
|
+
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',
|
|
38444
38583
|
type: 'button',
|
|
38445
|
-
children: jsx(
|
|
38446
|
-
className:
|
|
38584
|
+
children: showLoading ? jsx("div", {
|
|
38585
|
+
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'
|
|
38586
|
+
}) : jsx(EnvelopeIcon, {
|
|
38587
|
+
className: "babylai-w-4 babylai-h-4 babylai-flex-shrink-0 ".concat(dir === 'rtl' ? 'babylai-rotate-270' : '')
|
|
38447
38588
|
})
|
|
38448
38589
|
})]
|
|
38449
38590
|
}), previewImage && jsx(ImagePreviewDialog, {
|
|
@@ -38531,10 +38672,12 @@ var MessageComponent = /*#__PURE__*/React__default.memo(_ref => {
|
|
|
38531
38672
|
var isFirstHumanAgentMessage = index === firstHumanAgentIndex && message.senderType === 2;
|
|
38532
38673
|
var textDirection = message.senderType === 1 ? 'babylai-justify-end' : 'babylai-justify-start';
|
|
38533
38674
|
var handleImageClick = useCallback(clickedIndex => {
|
|
38534
|
-
if (
|
|
38535
|
-
|
|
38675
|
+
// Use attachmentUrls if available (from Ably), otherwise use attachmentIds (user-sent)
|
|
38676
|
+
var attachments = message.attachmentUrls || [];
|
|
38677
|
+
if (attachments.length > 0) {
|
|
38678
|
+
onImageClick(attachments, clickedIndex);
|
|
38536
38679
|
}
|
|
38537
|
-
}, [message.attachmentIds, onImageClick]);
|
|
38680
|
+
}, [message.attachmentIds, message.attachmentUrls, onImageClick]);
|
|
38538
38681
|
return jsxs("div", {
|
|
38539
38682
|
children: [isFirstHumanAgentMessage && jsx("div", {
|
|
38540
38683
|
className: 'babylai-flex babylai-justify-center babylai-items-center babylai-my-4',
|
|
@@ -38557,14 +38700,21 @@ var MessageComponent = /*#__PURE__*/React__default.memo(_ref => {
|
|
|
38557
38700
|
className: 'babylai-flex-shrink-0 babylai-me-3 babylai-w-8'
|
|
38558
38701
|
}), jsxs("div", {
|
|
38559
38702
|
className: 'babylai-flex babylai-flex-col babylai-gap-2',
|
|
38560
|
-
children: [message.
|
|
38703
|
+
children: [message.attachmentUrls && message.attachmentUrls.length > 0 && jsx("div", {
|
|
38704
|
+
className: 'babylai-flex babylai-flex-row babylai-flex-wrap babylai-gap-2 babylai-max-w-full',
|
|
38705
|
+
children: message.attachmentUrls.map((attachmentUrl, imgIndex) => jsx(ImageAttachment, {
|
|
38706
|
+
imageUrl: attachmentUrl,
|
|
38707
|
+
enablePreview: false,
|
|
38708
|
+
onClick: () => handleImageClick(imgIndex)
|
|
38709
|
+
}, attachmentUrl))
|
|
38710
|
+
}), message.attachmentIds && message.attachmentIds.length > 0 && jsx("div", {
|
|
38561
38711
|
className: 'babylai-flex babylai-flex-row babylai-flex-wrap babylai-gap-2 babylai-max-w-full',
|
|
38562
38712
|
children: message.attachmentIds.map((attachmentId, imgIndex) => jsx(ImageAttachment, {
|
|
38563
38713
|
fileId: attachmentId,
|
|
38564
38714
|
enablePreview: false,
|
|
38565
38715
|
onClick: () => handleImageClick(imgIndex)
|
|
38566
38716
|
}, attachmentId))
|
|
38567
|
-
}), jsx(AgentResponse$1, {
|
|
38717
|
+
}), message.messageContent && message.messageContent.trim() !== '' && jsx(AgentResponse$1, {
|
|
38568
38718
|
messageContent: message.messageContent,
|
|
38569
38719
|
senderType: message.senderType,
|
|
38570
38720
|
messageId: message.id,
|
|
@@ -38609,7 +38759,8 @@ var ChatWindow = /*#__PURE__*/React__default.memo(_ref3 => {
|
|
|
38609
38759
|
onEnsureSession,
|
|
38610
38760
|
messages,
|
|
38611
38761
|
assistantStatus = 'loading',
|
|
38612
|
-
needsAgent
|
|
38762
|
+
needsAgent,
|
|
38763
|
+
sessionId
|
|
38613
38764
|
} = _ref3;
|
|
38614
38765
|
var {
|
|
38615
38766
|
i18n
|
|
@@ -38652,7 +38803,8 @@ var ChatWindow = /*#__PURE__*/React__default.memo(_ref3 => {
|
|
|
38652
38803
|
};
|
|
38653
38804
|
}, []);
|
|
38654
38805
|
var handleSendMessage = useCallback(attachmentIds => {
|
|
38655
|
-
if
|
|
38806
|
+
// Allow sending if there's text OR attachments
|
|
38807
|
+
if (inputMessage.trim() || attachmentIds.length > 0) {
|
|
38656
38808
|
onSendMessage(inputMessage, attachmentIds);
|
|
38657
38809
|
setInputMessage('');
|
|
38658
38810
|
}
|
|
@@ -38663,13 +38815,32 @@ var ChatWindow = /*#__PURE__*/React__default.memo(_ref3 => {
|
|
|
38663
38815
|
}, [messages]);
|
|
38664
38816
|
// Handle image gallery opening
|
|
38665
38817
|
var handleImageClick = useCallback(/*#__PURE__*/function () {
|
|
38666
|
-
var _ref4 = _asyncToGenerator(function* (
|
|
38667
|
-
|
|
38818
|
+
var _ref4 = _asyncToGenerator(function* (attachmentIdsOrUrls, clickedIndex) {
|
|
38819
|
+
var _a, _b;
|
|
38820
|
+
if (!attachmentIdsOrUrls || attachmentIdsOrUrls.length === 0) {
|
|
38668
38821
|
return;
|
|
38669
38822
|
}
|
|
38670
38823
|
try {
|
|
38671
|
-
//
|
|
38672
|
-
|
|
38824
|
+
// Check if the first item is a URL (starts with http:// or https://)
|
|
38825
|
+
// If so, they're all URLs from Ably and can be used directly
|
|
38826
|
+
var isUrl = ((_a = attachmentIdsOrUrls[0]) === null || _a === void 0 ? void 0 : _a.startsWith('http://')) || ((_b = attachmentIdsOrUrls[0]) === null || _b === void 0 ? void 0 : _b.startsWith('https://'));
|
|
38827
|
+
var imageUrls;
|
|
38828
|
+
if (isUrl) {
|
|
38829
|
+
// These are already URLs from Ably, use them directly (no async needed)
|
|
38830
|
+
imageUrls = attachmentIdsOrUrls.filter(url => url !== null && url.length > 0);
|
|
38831
|
+
// Open gallery immediately with URLs
|
|
38832
|
+
if (imageUrls.length > 0) {
|
|
38833
|
+
var _adjustedIndex = Math.max(0, Math.min(clickedIndex, imageUrls.length - 1));
|
|
38834
|
+
setGalleryState({
|
|
38835
|
+
isOpen: true,
|
|
38836
|
+
imageUrls,
|
|
38837
|
+
initialIndex: _adjustedIndex
|
|
38838
|
+
});
|
|
38839
|
+
}
|
|
38840
|
+
return; // Exit early since we don't need to fetch anything
|
|
38841
|
+
}
|
|
38842
|
+
// These are file IDs, need to fetch URLs using presignDownload
|
|
38843
|
+
var imageUrlPromises = attachmentIdsOrUrls.map(fileId => {
|
|
38673
38844
|
if (!fileId || typeof fileId !== 'string') {
|
|
38674
38845
|
return Promise.resolve(null);
|
|
38675
38846
|
}
|
|
@@ -38683,7 +38854,7 @@ var ChatWindow = /*#__PURE__*/React__default.memo(_ref3 => {
|
|
|
38683
38854
|
return null;
|
|
38684
38855
|
});
|
|
38685
38856
|
});
|
|
38686
|
-
|
|
38857
|
+
imageUrls = (yield Promise.all(imageUrlPromises)).filter(url => url !== null && url.length > 0);
|
|
38687
38858
|
if (imageUrls.length === 0) {
|
|
38688
38859
|
return;
|
|
38689
38860
|
}
|
|
@@ -38745,7 +38916,8 @@ var ChatWindow = /*#__PURE__*/React__default.memo(_ref3 => {
|
|
|
38745
38916
|
handleSendMessage: handleSendMessage,
|
|
38746
38917
|
setInputMessage: setInputMessage,
|
|
38747
38918
|
isLoading: isLoading,
|
|
38748
|
-
onEnsureSession: onEnsureSession
|
|
38919
|
+
onEnsureSession: onEnsureSession,
|
|
38920
|
+
sessionId: sessionId
|
|
38749
38921
|
}), galleryState.isOpen && galleryState.imageUrls.length > 0 && jsx(ImagePreviewDialog, {
|
|
38750
38922
|
imageUrls: galleryState.imageUrls,
|
|
38751
38923
|
initialIndex: galleryState.initialIndex,
|
|
@@ -39364,7 +39536,8 @@ var HelpPopup = _ref => {
|
|
|
39364
39536
|
}
|
|
39365
39537
|
}, [onStartChat, setSelectedOption, sessionId, setStartNewChatConfirmation, setTempSelectedOption]);
|
|
39366
39538
|
var handleSendMessage = useCallback((message, attachmentIds) => {
|
|
39367
|
-
if
|
|
39539
|
+
// Allow sending if there's text OR attachments
|
|
39540
|
+
if (message.trim() || attachmentIds.length > 0) {
|
|
39368
39541
|
onSendMessage(message.trim(), attachmentIds);
|
|
39369
39542
|
}
|
|
39370
39543
|
}, [onSendMessage]);
|
|
@@ -39420,7 +39593,8 @@ var HelpPopup = _ref => {
|
|
|
39420
39593
|
messages: memoizedMessages,
|
|
39421
39594
|
assistantStatus: assistantStatus,
|
|
39422
39595
|
needsAgent: needsAgent,
|
|
39423
|
-
isAblyConnected: isAblyConnected
|
|
39596
|
+
isAblyConnected: isAblyConnected,
|
|
39597
|
+
sessionId: sessionId
|
|
39424
39598
|
})]
|
|
39425
39599
|
});
|
|
39426
39600
|
}
|
|
@@ -39559,7 +39733,7 @@ var HelpCenterContent = _ref => {
|
|
|
39559
39733
|
sentAt: new Date(),
|
|
39560
39734
|
isSeen: true
|
|
39561
39735
|
}, attachments.length > 0 && {
|
|
39562
|
-
|
|
39736
|
+
attachmentUrls: attachments
|
|
39563
39737
|
});
|
|
39564
39738
|
return [...prevMessages, newMessage];
|
|
39565
39739
|
});
|
|
@@ -39688,10 +39862,11 @@ var HelpCenterContent = _ref => {
|
|
|
39688
39862
|
var handleEnsureSession = /*#__PURE__*/function () {
|
|
39689
39863
|
var _ref7 = _asyncToGenerator(function* () {
|
|
39690
39864
|
// If we already have a session ID and connection, return it
|
|
39691
|
-
if
|
|
39865
|
+
// NEVER create a new session if one already exists
|
|
39866
|
+
if (sessionId) {
|
|
39692
39867
|
return sessionId;
|
|
39693
39868
|
}
|
|
39694
|
-
//
|
|
39869
|
+
// Only create a new session if we don't have one and have a selected option
|
|
39695
39870
|
if (selectedOption) {
|
|
39696
39871
|
var newSessionId = yield startNewChatSession(selectedOption);
|
|
39697
39872
|
return newSessionId;
|
|
@@ -39705,28 +39880,32 @@ var HelpCenterContent = _ref => {
|
|
|
39705
39880
|
var handleSendMessage = /*#__PURE__*/function () {
|
|
39706
39881
|
var _ref8 = _asyncToGenerator(function* (message) {
|
|
39707
39882
|
var attachmentIds = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
39708
|
-
|
|
39883
|
+
// Allow sending if there's text OR attachments
|
|
39884
|
+
if (message.trim() !== '' || attachmentIds.length > 0) {
|
|
39709
39885
|
try {
|
|
39710
39886
|
setAssistantStatus('typing');
|
|
39711
39887
|
var userMessage = {
|
|
39712
39888
|
id: Date.now(),
|
|
39713
39889
|
senderType: 1,
|
|
39714
|
-
messageContent: message,
|
|
39890
|
+
messageContent: message || '',
|
|
39891
|
+
// Use empty string if message is empty but attachments exist
|
|
39715
39892
|
sentAt: new Date(),
|
|
39716
39893
|
isSeen: false,
|
|
39717
39894
|
attachmentIds: attachmentIds.length > 0 ? attachmentIds : undefined
|
|
39718
39895
|
};
|
|
39719
39896
|
setMessages(prevMessages => [...prevMessages, userMessage]);
|
|
39720
|
-
// Handle session creation if needed
|
|
39897
|
+
// Handle session creation if needed - only create if no session exists
|
|
39721
39898
|
var currentSessionId = sessionId;
|
|
39722
|
-
if
|
|
39899
|
+
// Only create a new session if we don't have one and we have a selected option
|
|
39900
|
+
// This ensures session is only created once with the first message
|
|
39901
|
+
if (!currentSessionId && !isAblyConnected && selectedOption) {
|
|
39723
39902
|
currentSessionId = yield startNewChatSession(selectedOption);
|
|
39724
39903
|
}
|
|
39725
39904
|
if (!currentSessionId) {
|
|
39726
39905
|
throw new Error('No active session available');
|
|
39727
39906
|
}
|
|
39728
39907
|
var messageDto = _objectSpread2({
|
|
39729
|
-
messageContent: message
|
|
39908
|
+
messageContent: message || ''
|
|
39730
39909
|
}, attachmentIds.length > 0 && {
|
|
39731
39910
|
attachmentIds
|
|
39732
39911
|
});
|