embeddedaichatux 2.2.0 → 2.2.1
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/EmbeddedChat.js +167 -140
- package/package.json +1 -1
package/EmbeddedChat.js
CHANGED
|
@@ -13,16 +13,17 @@
|
|
|
13
13
|
this.options = options || {};
|
|
14
14
|
this.isPreview = this.options.isPreview || false;
|
|
15
15
|
this.locale = options.locale || 'en';
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
this.serverUrl = this.options.serverUrl || 'https://app.bizdriver.ai/';
|
|
18
18
|
this.height = options.height || 600; // Default height
|
|
19
|
-
this.width = options.width ||
|
|
19
|
+
this.width = options.width || 400; // Default width
|
|
20
20
|
this.marginBottom = options.marginBottom || 0;
|
|
21
21
|
this.enableAnimation = options.enableAnimation !== false; // Default to true if not provided
|
|
22
|
-
this.
|
|
22
|
+
this.theme = options.theme || this.containerDiv.dataset.theme || 'Standard';
|
|
23
|
+
this.minimizedHeight = this.theme === 'MinimalInput' ? "75px" : "80px"; // Default heights for different themes
|
|
23
24
|
this.hasMeasuredSize = false;
|
|
24
25
|
this.mouseInsideChat = false;
|
|
25
|
-
|
|
26
|
+
|
|
26
27
|
this.conversationId = null;
|
|
27
28
|
this.userTokenProvider = options.userTokenProvider;
|
|
28
29
|
this.targetOrigin = "*";
|
|
@@ -33,7 +34,9 @@
|
|
|
33
34
|
this.position = this.options.position || this.containerDiv.dataset.position || 'fixed';
|
|
34
35
|
this.positionStyle = this.position === 'in-place' ?
|
|
35
36
|
`position: relative; width:100%; height:${this.height}px; ${transitionStyle}` :
|
|
36
|
-
|
|
37
|
+
(this.theme === 'MinimalInput' ?
|
|
38
|
+
`position: fixed; left: 0; right: 0; margin-left: auto; margin-right: auto; width: 100%; max-width: ${this.width}px; bottom: ${this.marginBottom}px; z-index: 100000; max-height: 90vh; ${transitionStyle}` :
|
|
39
|
+
`position: fixed; right: 1em; bottom: ${this.marginBottom}px; width: 100%; max-width: ${this.width}px; z-index: 100000; max-height: 90vh; ${transitionStyle}`);
|
|
37
40
|
this.mode = options.mode || 'Chat'; // default to 'chat'
|
|
38
41
|
this.minimizeOnScroll = false; // Default to false
|
|
39
42
|
if (this.mode === 'ContactForm' || this.mode === 'PartnerOffers') {
|
|
@@ -93,13 +96,25 @@
|
|
|
93
96
|
? this.serverUrl.slice(0, -1)
|
|
94
97
|
: this.serverUrl;
|
|
95
98
|
const baseIframeUrl = `${cleanedServerUrl}/ChatUX/${this.chatId}`;
|
|
99
|
+
const transitionStyle = this.enableAnimation ? 'transition: height 0.3s ease, opacity 0.3s ease;' : '';
|
|
100
|
+
|
|
101
|
+
// Recalculate positionStyle conditionally in case theme changed dynamically
|
|
102
|
+
this.positionStyle = this.position === 'in-place' ?
|
|
103
|
+
`position: relative; width:100%; height:${this.height}px; ${transitionStyle}` :
|
|
104
|
+
(this.theme === 'MinimalInput' ?
|
|
105
|
+
`position: fixed; left: 0; right: 0; margin-left: auto; margin-right: auto; bottom: ${this.marginBottom}px; width: 95vw; max-width: ${this.width}px; z-index: 100000; max-height: 90vh; pointer-events: auto; ${transitionStyle}` :
|
|
106
|
+
`position: fixed; right: 1em; bottom: ${this.marginBottom}px; width: ${this.width}px; z-index: 100000; max-width:90vw; max-height: 90vh; pointer-events: auto; ${transitionStyle}`);
|
|
107
|
+
|
|
96
108
|
const minimizedPositionStyle = this.position === 'in-place' ?
|
|
97
|
-
`position: relative; width: 100%; height: ${this.minimizedHeight}; ${
|
|
98
|
-
|
|
109
|
+
`position: relative; width: 100%; height: ${this.minimizedHeight}; ${transitionStyle}` :
|
|
110
|
+
(this.theme === 'MinimalInput' ?
|
|
111
|
+
`position: fixed; left: 0; right: 0; margin-left: auto; margin-right: auto; bottom: ${this.marginBottom}px; width: 100vw; max-width: ${Math.min(300, this.width) + 40}px; height: ${this.minimizedHeight}; z-index: 100000; pointer-events: auto; ${transitionStyle}` :
|
|
112
|
+
`position: fixed; right: 0; bottom: ${this.marginBottom}px; width: 150px; height: ${this.minimizedHeight}; z-index: 100000; max-width: 95vw; pointer-events: auto; ${transitionStyle}`);
|
|
99
113
|
|
|
100
114
|
const params = {
|
|
101
115
|
isPreview: this.isPreview,
|
|
102
116
|
mode: this.mode,
|
|
117
|
+
theme: this.theme,
|
|
103
118
|
locale: this.locale,
|
|
104
119
|
conversationId: this.conversationId,
|
|
105
120
|
instanceId: this.instanceId,
|
|
@@ -144,11 +159,18 @@
|
|
|
144
159
|
// Send auth to iframes after load
|
|
145
160
|
await this.postAuthToIframes();
|
|
146
161
|
|
|
147
|
-
//
|
|
162
|
+
// Restore ContactForm logic
|
|
148
163
|
if (this.mode === 'ContactForm' || this.mode === 'PartnerOffers') {
|
|
149
164
|
this.iframe.style.maxWidth = '100%';
|
|
150
165
|
this.iframe.style.display = 'block';
|
|
151
166
|
}
|
|
167
|
+
|
|
168
|
+
// Apply pointer-events to container if theme is MinimalInput to prevent blocking page
|
|
169
|
+
if (this.theme === 'MinimalInput' && this.position !== 'in-place') {
|
|
170
|
+
this.containerDiv.style.pointerEvents = 'none';
|
|
171
|
+
} else {
|
|
172
|
+
this.containerDiv.style.pointerEvents = 'auto'; // Reset for other themes
|
|
173
|
+
}
|
|
152
174
|
}
|
|
153
175
|
|
|
154
176
|
addIframeEventListeners() {
|
|
@@ -163,12 +185,9 @@
|
|
|
163
185
|
}
|
|
164
186
|
|
|
165
187
|
addWindowEventListeners() {
|
|
166
|
-
|
|
167
|
-
// Use a flag to ensure window listeners aren't duplicated for this specific instance if setMode is called (though it shouldn't be)
|
|
168
188
|
if (this.windowListenersAdded) return;
|
|
169
189
|
|
|
170
190
|
window.addEventListener("message", (e) => {
|
|
171
|
-
// Only trust messages from our server (when targetOrigin is not "*")
|
|
172
191
|
if (this.targetOrigin !== "*" && e.origin !== this.targetOrigin) return;
|
|
173
192
|
this.handleMessage(e);
|
|
174
193
|
});
|
|
@@ -197,7 +216,7 @@
|
|
|
197
216
|
if (this.iframe?.contentWindow) {
|
|
198
217
|
this.iframe.contentWindow.postMessage({
|
|
199
218
|
message: "resize",
|
|
200
|
-
width: window.innerWidth,
|
|
219
|
+
width: window.innerWidth,
|
|
201
220
|
height: window.innerHeight,
|
|
202
221
|
instanceId: this.instanceId
|
|
203
222
|
}, this.targetOrigin);
|
|
@@ -205,11 +224,9 @@
|
|
|
205
224
|
}
|
|
206
225
|
|
|
207
226
|
handleMessage(e) {
|
|
208
|
-
// Only trust messages from our server (when targetOrigin is not "*")
|
|
209
227
|
if (this.targetOrigin !== "*" && e.origin !== this.targetOrigin) return;
|
|
210
228
|
|
|
211
229
|
if (typeof e.data !== "object") {
|
|
212
|
-
// Preserve original handling for string messages
|
|
213
230
|
if (typeof e.data === "string") {
|
|
214
231
|
if (e.data === "minimize") {
|
|
215
232
|
this.animateMinimize();
|
|
@@ -234,56 +251,68 @@
|
|
|
234
251
|
const targetChatId = (this.chatId || "").toString().toLowerCase();
|
|
235
252
|
const incomingInstanceId = data.instanceId;
|
|
236
253
|
|
|
237
|
-
// Priority 1: Handle instance-specific routing
|
|
238
254
|
if (incomingInstanceId && incomingInstanceId !== this.instanceId) return;
|
|
239
|
-
|
|
240
|
-
// Priority 2: Bail out if chatId doesn't match and is provided (legacy/fallback)
|
|
241
255
|
if (!incomingInstanceId && incomingChatId && targetChatId && incomingChatId !== targetChatId) return;
|
|
242
256
|
|
|
243
|
-
// Allow the iframe to request a fresh token
|
|
244
257
|
if (data.type === "requestAuth") {
|
|
245
258
|
this.postAuthToIframes();
|
|
246
259
|
return;
|
|
247
260
|
}
|
|
248
261
|
|
|
249
|
-
// Priority 1: Handle minimized size updates (CRITICAL: Bail out early and DO NOT pollute configuration)
|
|
250
262
|
if (msg === "updateMinimizedSize") {
|
|
251
|
-
// Support both new and legacy keys for compatibility with cached scripts
|
|
252
263
|
const h = data.minimizedHeight || data.height;
|
|
253
264
|
const w = data.minimizedWidth || data.width;
|
|
254
265
|
this.updateMinimizedSize(h, w);
|
|
255
266
|
return;
|
|
256
267
|
}
|
|
257
268
|
|
|
258
|
-
|
|
269
|
+
if (msg === "collapseMinimalInput") {
|
|
270
|
+
if (this.minimizedIframe) {
|
|
271
|
+
this.minimizedIframe.style.width = '80px';
|
|
272
|
+
this.minimizedIframe.style.height = '80px';
|
|
273
|
+
this.minimizedIframe.style.left = 'auto';
|
|
274
|
+
this.minimizedIframe.style.right = '0';
|
|
275
|
+
this.minimizedIframe.style.marginLeft = '0';
|
|
276
|
+
this.minimizedIframe.style.marginRight = '0';
|
|
277
|
+
this.minimizedIframe.style.pointerEvents = 'auto';
|
|
278
|
+
}
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
if (msg === "restoreMinimalInput") {
|
|
283
|
+
if (this.minimizedIframe) {
|
|
284
|
+
this.minimizedIframe.style.width = '100vw';
|
|
285
|
+
this.minimizedIframe.style.maxWidth = `${Math.min(300, this.width) + 40}px`;
|
|
286
|
+
this.minimizedIframe.style.height = this.theme === 'MinimalInput' ? "75px" : this.minimizedHeight;
|
|
287
|
+
this.minimizedIframe.style.left = '0';
|
|
288
|
+
this.minimizedIframe.style.right = '0';
|
|
289
|
+
this.minimizedIframe.style.marginLeft = 'auto';
|
|
290
|
+
this.minimizedIframe.style.marginRight = 'auto';
|
|
291
|
+
this.minimizedIframe.style.pointerEvents = 'auto';
|
|
292
|
+
}
|
|
293
|
+
if (this.theme === 'MinimalInput' && this.position !== 'in-place') {
|
|
294
|
+
this.containerDiv.style.pointerEvents = 'none';
|
|
295
|
+
}
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
259
298
|
|
|
299
|
+
const updates = {};
|
|
260
300
|
if (data.type === "setMinimizeOnScroll" || data.minimizeOnScroll !== undefined) {
|
|
261
301
|
const minimizeValue = data.type === "setMinimizeOnScroll" ? data.value : data.minimizeOnScroll;
|
|
262
302
|
this.minimizeOnScroll = minimizeValue === true || minimizeValue === "true";
|
|
263
303
|
}
|
|
264
304
|
|
|
265
|
-
if (data.locale)
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if (data.
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (data.height) {
|
|
272
|
-
updates.height = data.height;
|
|
273
|
-
}
|
|
274
|
-
if (data.marginBottom) {
|
|
275
|
-
updates.marginBottom = data.marginBottom;
|
|
276
|
-
}
|
|
277
|
-
if (data.scale) {
|
|
278
|
-
updates.scale = data.scale;
|
|
279
|
-
}
|
|
305
|
+
if (data.locale) updates.locale = data.locale;
|
|
306
|
+
if (data.width) updates.width = data.width;
|
|
307
|
+
if (data.height) updates.height = data.height;
|
|
308
|
+
if (data.marginBottom) updates.marginBottom = data.marginBottom;
|
|
309
|
+
if (data.scale) updates.scale = data.scale;
|
|
310
|
+
if (data.theme) updates.theme = data.theme;
|
|
280
311
|
|
|
281
|
-
// Apply iframe updates in one go
|
|
282
312
|
if (Object.keys(updates).length > 0) {
|
|
283
313
|
this.applyIframeUpdates(updates);
|
|
284
314
|
}
|
|
285
315
|
|
|
286
|
-
// Handle maximize/minimize/navigate
|
|
287
316
|
if (msg === "minimize") {
|
|
288
317
|
if (typeof this.options.onMinimize === 'function') {
|
|
289
318
|
this.options.onMinimize();
|
|
@@ -292,7 +321,7 @@
|
|
|
292
321
|
}
|
|
293
322
|
} else if (msg === "show" || msg === "maximize") {
|
|
294
323
|
const animate = data.animate === true;
|
|
295
|
-
this.showMaximized(animate);
|
|
324
|
+
this.showMaximized(animate, data.initialMessage);
|
|
296
325
|
} else if (msg === "navigate" && data.url) {
|
|
297
326
|
window.location.href = data.url;
|
|
298
327
|
} else if (data.type === "switchToChat" || msg === "switchToChat") {
|
|
@@ -309,7 +338,6 @@
|
|
|
309
338
|
}
|
|
310
339
|
}
|
|
311
340
|
|
|
312
|
-
// Handle conversationId update
|
|
313
341
|
if (data.conversationId) {
|
|
314
342
|
this.setConversationId(data.conversationId);
|
|
315
343
|
}
|
|
@@ -326,7 +354,6 @@
|
|
|
326
354
|
this.minimizedIframe.style.height = this.minimizedHeight;
|
|
327
355
|
this.minimizedIframe.style.opacity = '1';
|
|
328
356
|
|
|
329
|
-
// Request a height update after showing
|
|
330
357
|
if (this.minimizedIframe.contentWindow) {
|
|
331
358
|
this.minimizedIframe.contentWindow.postMessage({ message: "requestHeightUpdate", instanceId: this.instanceId }, this.targetOrigin);
|
|
332
359
|
}
|
|
@@ -339,7 +366,6 @@
|
|
|
339
366
|
|
|
340
367
|
this.hasMeasuredSize = true;
|
|
341
368
|
|
|
342
|
-
// Apply height update
|
|
343
369
|
if (contentHeight && contentHeight >= 10) {
|
|
344
370
|
const newHeight = `${contentHeight}px`;
|
|
345
371
|
this.minimizedHeight = newHeight;
|
|
@@ -348,9 +374,8 @@
|
|
|
348
374
|
}
|
|
349
375
|
}
|
|
350
376
|
|
|
351
|
-
// Apply width update
|
|
352
377
|
if (contentWidth && contentWidth >= 10) {
|
|
353
|
-
if (this.minimizedIframe) {
|
|
378
|
+
if (this.minimizedIframe && this.theme !== 'MinimalInput') {
|
|
354
379
|
this.minimizedIframe.style.width = `${contentWidth}px`;
|
|
355
380
|
}
|
|
356
381
|
}
|
|
@@ -358,97 +383,126 @@
|
|
|
358
383
|
|
|
359
384
|
animateMaximize() {
|
|
360
385
|
if (this.mode !== 'ContactForm' && this.mode !== 'PartnerOffers') {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
this.minimizedIframe.style.opacity = '0';
|
|
364
|
-
|
|
365
|
-
setTimeout(() => {
|
|
366
|
-
// Hide the minimized iframe
|
|
386
|
+
const onMinimizedAnimateEnd = () => {
|
|
387
|
+
this.minimizedIframe.removeEventListener("transitionend", onMinimizedAnimateEnd);
|
|
367
388
|
this.minimizedIframe.style.display = "none";
|
|
368
|
-
this.minimizedIframe.style.opacity = '1';
|
|
389
|
+
this.minimizedIframe.style.opacity = '1';
|
|
369
390
|
|
|
370
|
-
// Show and animate the main iframe
|
|
371
391
|
this.iframe.style.display = "block";
|
|
372
|
-
this.iframe.style.height = this.minimizedHeight;
|
|
373
|
-
this.iframe.style.opacity =
|
|
392
|
+
this.iframe.style.height = this.minimizedHeight;
|
|
393
|
+
this.iframe.style.opacity = "0";
|
|
374
394
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
395
|
+
this.iframe.offsetHeight;
|
|
396
|
+
|
|
397
|
+
this.iframe.style.height = `${this.height}px`;
|
|
398
|
+
this.iframe.style.opacity = "1";
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
if (this.enableAnimation) {
|
|
402
|
+
this.minimizedIframe.addEventListener("transitionend", onMinimizedAnimateEnd);
|
|
403
|
+
this.minimizedIframe.style.height = this.minimizedHeight;
|
|
404
|
+
this.minimizedIframe.style.opacity = "0";
|
|
405
|
+
|
|
406
|
+
// Notify iframe when maximize transition finishes to ensure final scroll-into-view
|
|
407
|
+
this.iframe.addEventListener("transitionend", (e) => {
|
|
408
|
+
if (e.propertyName === 'height' && this.iframe.style.display !== 'none') {
|
|
409
|
+
if (this.iframe.contentWindow) {
|
|
410
|
+
this.iframe.contentWindow.postMessage({ message: "maximizeComplete", instanceId: this.instanceId }, this.targetOrigin);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}, { once: true });
|
|
414
|
+
} else {
|
|
415
|
+
onMinimizedAnimateEnd();
|
|
416
|
+
}
|
|
381
417
|
}
|
|
382
418
|
}
|
|
383
419
|
|
|
384
|
-
applyIframeUpdates({ locale, width, height, marginBottom, scale } = {}) {
|
|
385
|
-
|
|
420
|
+
applyIframeUpdates({ locale, width, height, marginBottom, scale, theme } = {}) {
|
|
421
|
+
if (theme && typeof theme === 'string' && theme !== this.theme) {
|
|
422
|
+
this.theme = theme;
|
|
423
|
+
console.log(`Theme updated to: ${this.theme}`);
|
|
424
|
+
this.minimizedHeight = this.theme === 'MinimalInput' ? "75px" : "80px";
|
|
425
|
+
this.updateIframes();
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
|
|
386
429
|
if (locale && typeof locale === 'string' && locale !== this.locale) {
|
|
387
430
|
this.locale = locale;
|
|
388
431
|
console.log(`Locale stored locally: ${this.locale}`);
|
|
389
432
|
}
|
|
390
433
|
|
|
391
|
-
// Update width if provided and different
|
|
392
434
|
const parsedWidth = parseInt(width, 10);
|
|
393
435
|
if (!isNaN(parsedWidth) && parsedWidth > 0 && parsedWidth !== this.width) {
|
|
394
436
|
this.width = parsedWidth;
|
|
395
437
|
console.log(`Width updated to: ${this.width}px`);
|
|
396
438
|
|
|
397
|
-
// Apply width only if not in-place
|
|
398
439
|
if (this.position !== 'in-place') {
|
|
399
|
-
this.
|
|
400
|
-
|
|
401
|
-
this.
|
|
440
|
+
if (this.theme === 'MinimalInput') {
|
|
441
|
+
this.containerDiv.style.width = '100vw'; // Use 100vw but keep pointerEvents none
|
|
442
|
+
this.containerDiv.style.left = '0';
|
|
443
|
+
this.containerDiv.style.right = '0';
|
|
444
|
+
this.containerDiv.style.marginLeft = 'auto';
|
|
445
|
+
this.containerDiv.style.marginRight = 'auto';
|
|
446
|
+
this.containerDiv.style.pointerEvents = 'none'; // Prevent invisible area from blocking clicks
|
|
447
|
+
if (this.iframe) {
|
|
448
|
+
this.iframe.style.width = '95vw';
|
|
449
|
+
this.iframe.style.maxWidth = `${this.width}px`;
|
|
450
|
+
this.iframe.style.pointerEvents = 'auto';
|
|
451
|
+
this.iframe.style.left = '0';
|
|
452
|
+
this.iframe.style.right = '0';
|
|
453
|
+
this.iframe.style.margin = 'auto';
|
|
454
|
+
}
|
|
455
|
+
if (this.minimizedIframe) {
|
|
456
|
+
this.minimizedIframe.style.width = '100vw'; // Use 100vw to allow centering
|
|
457
|
+
this.minimizedIframe.style.maxWidth = `${Math.min(300, this.width) + 40}px`;
|
|
458
|
+
this.minimizedIframe.style.pointerEvents = 'auto';
|
|
459
|
+
this.minimizedIframe.style.left = '0';
|
|
460
|
+
this.minimizedIframe.style.right = '0';
|
|
461
|
+
this.minimizedIframe.style.margin = 'auto';
|
|
462
|
+
}
|
|
463
|
+
} else {
|
|
464
|
+
this.containerDiv.style.width = `${this.width}px`;
|
|
465
|
+
this.containerDiv.style.pointerEvents = 'auto'; // Ensure auto for other themes
|
|
466
|
+
if (this.iframe) this.iframe.style.width = `${this.width}px`;
|
|
402
467
|
}
|
|
403
468
|
} else {
|
|
404
469
|
this.containerDiv.style.width = '100%';
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
}
|
|
470
|
+
this.containerDiv.style.pointerEvents = 'auto';
|
|
471
|
+
if (this.iframe) this.iframe.style.width = '100%';
|
|
408
472
|
}
|
|
409
473
|
}
|
|
410
474
|
|
|
411
|
-
// Apply scale if provided
|
|
412
475
|
if (typeof scale === 'number' && scale > 0) {
|
|
413
476
|
this.applyScale(scale);
|
|
414
477
|
console.log(`Scale applied: ${scale}`);
|
|
415
478
|
}
|
|
416
479
|
|
|
417
|
-
// Handle height and marginBottom
|
|
418
480
|
let parsedHeight = parseInt(height, 10);
|
|
419
481
|
let parsedMarginBottom = parseInt(marginBottom, 10);
|
|
420
482
|
|
|
421
|
-
|
|
422
|
-
if (isNaN(parsedHeight) || parsedHeight <= 0) {
|
|
423
|
-
parsedHeight = this.height;
|
|
424
|
-
}
|
|
483
|
+
if (isNaN(parsedHeight) || parsedHeight <= 0) parsedHeight = this.height;
|
|
425
484
|
if (isNaN(parsedMarginBottom) || parsedMarginBottom < 0) {
|
|
426
485
|
parsedMarginBottom = (typeof this.marginBottom === 'number') ? this.marginBottom : 0;
|
|
427
486
|
}
|
|
428
487
|
|
|
429
|
-
// Clamp so that height + marginBottom doesn't exceed 90% of viewport
|
|
430
488
|
const viewportHeight = window.innerHeight;
|
|
431
489
|
let effectiveHeight = parsedHeight;
|
|
432
490
|
if (effectiveHeight + parsedMarginBottom > 0.9 * viewportHeight) {
|
|
433
491
|
effectiveHeight = Math.max(100, 0.9 * viewportHeight - parsedMarginBottom);
|
|
434
492
|
}
|
|
435
493
|
|
|
436
|
-
// Only apply if there's an actual change
|
|
437
494
|
if (parsedHeight !== this.height || parsedMarginBottom !== this.marginBottom) {
|
|
438
495
|
this.height = parsedHeight;
|
|
439
496
|
this.marginBottom = parsedMarginBottom;
|
|
440
497
|
|
|
441
|
-
// Only use the 30% estimate if we haven't received a real measurement yet
|
|
442
498
|
if (!this.hasMeasuredSize) {
|
|
443
|
-
this.minimizedHeight =
|
|
499
|
+
this.minimizedHeight = this.theme === 'MinimalInput' ? "75px" : "80px";
|
|
444
500
|
}
|
|
445
501
|
|
|
446
|
-
console.log(`Height updated to: ${this.height}px
|
|
502
|
+
console.log(`Height updated to: ${this.height}px, marginBottom: ${this.marginBottom}px`);
|
|
447
503
|
|
|
448
|
-
// Apply the updated height/marginBottom
|
|
449
504
|
if (this.mode !== 'ContactForm' && this.mode !== 'PartnerOffers') {
|
|
450
505
|
if (this.position === 'in-place') {
|
|
451
|
-
// "in-place" uses full width, sets containerDiv height
|
|
452
506
|
this.containerDiv.style.position = 'relative';
|
|
453
507
|
this.containerDiv.style.width = '100%';
|
|
454
508
|
this.containerDiv.style.height = `${effectiveHeight}px`;
|
|
@@ -467,8 +521,6 @@
|
|
|
467
521
|
this.minimizedIframe.style.right = 'unset';
|
|
468
522
|
}
|
|
469
523
|
} else {
|
|
470
|
-
// position: fixed (typical floating chat)
|
|
471
|
-
// Update bottom offset, main height
|
|
472
524
|
if (this.iframe) {
|
|
473
525
|
this.iframe.style.height = `${this.height}px`;
|
|
474
526
|
this.iframe.style.bottom = `${this.marginBottom}px`;
|
|
@@ -476,34 +528,36 @@
|
|
|
476
528
|
if (this.minimizedIframe) {
|
|
477
529
|
this.minimizedIframe.style.height = this.minimizedHeight;
|
|
478
530
|
this.minimizedIframe.style.bottom = `${this.marginBottom}px`;
|
|
531
|
+
if (this.theme === 'MinimalInput') {
|
|
532
|
+
this.minimizedIframe.style.width = '100vw';
|
|
533
|
+
this.minimizedIframe.style.maxWidth = `${Math.min(300, this.width) + 40}px`;
|
|
534
|
+
}
|
|
479
535
|
}
|
|
480
536
|
}
|
|
481
537
|
} else {
|
|
482
|
-
// ContactForm mode
|
|
483
538
|
this.containerDiv.style.height = `${this.height}px`;
|
|
484
|
-
if (this.iframe) {
|
|
485
|
-
this.iframe.style.height = `${this.height}px`;
|
|
486
|
-
}
|
|
539
|
+
if (this.iframe) this.iframe.style.height = `${this.height}px`;
|
|
487
540
|
}
|
|
488
541
|
}
|
|
489
542
|
}
|
|
490
543
|
|
|
491
|
-
showMaximized(animate = false) {
|
|
544
|
+
showMaximized(animate = false, initialMessage = null) {
|
|
492
545
|
const schedulePostMessage = () => {
|
|
493
546
|
if (this.iframe.contentWindow) {
|
|
494
547
|
this.iframe.contentWindow.postMessage({
|
|
495
548
|
message: "show",
|
|
496
549
|
sessionInfo: this.sessionInfo || null,
|
|
497
|
-
instanceId: this.instanceId
|
|
550
|
+
instanceId: this.instanceId,
|
|
551
|
+
initialMessage: initialMessage
|
|
498
552
|
}, this.targetOrigin);
|
|
499
553
|
} else {
|
|
500
|
-
// Schedule a single retry with a delay
|
|
501
554
|
setTimeout(() => {
|
|
502
555
|
if (this.iframe.contentWindow) {
|
|
503
556
|
this.iframe.contentWindow.postMessage({
|
|
504
557
|
message: "show",
|
|
505
558
|
sessionInfo: this.sessionInfo || null,
|
|
506
|
-
instanceId: this.instanceId
|
|
559
|
+
instanceId: this.instanceId,
|
|
560
|
+
initialMessage: initialMessage
|
|
507
561
|
}, this.targetOrigin);
|
|
508
562
|
} else {
|
|
509
563
|
console.warn("iframe contentWindow is not available.");
|
|
@@ -516,8 +570,7 @@
|
|
|
516
570
|
this.animateMaximize();
|
|
517
571
|
} else {
|
|
518
572
|
this.minimizedIframe.style.display = "none";
|
|
519
|
-
this.minimizedIframe.style.
|
|
520
|
-
this.minimizedIframe.style.opacity = ''; // Reset opacity to unset
|
|
573
|
+
this.minimizedIframe.style.opacity = '';
|
|
521
574
|
|
|
522
575
|
this.iframe.style.display = "block";
|
|
523
576
|
this.iframe.style.height = `${this.height}px`;
|
|
@@ -529,7 +582,8 @@
|
|
|
529
582
|
|
|
530
583
|
applyScale(scale) {
|
|
531
584
|
if (this.mode !== 'ContactForm' && this.mode !== 'PartnerOffers') {
|
|
532
|
-
|
|
585
|
+
let origin = this.position === 'in-place' ? 'top center' : 'bottom right';
|
|
586
|
+
if (this.theme === 'MinimalInput') origin = 'bottom center';
|
|
533
587
|
if (this.iframe) {
|
|
534
588
|
this.iframe.style.transform = `scale(${scale})`;
|
|
535
589
|
this.iframe.style.transformOrigin = origin;
|
|
@@ -548,10 +602,7 @@
|
|
|
548
602
|
}
|
|
549
603
|
|
|
550
604
|
setSessionInfo(sessionInfo) {
|
|
551
|
-
console.log('setSessionInfo called with sessionInfo:', sessionInfo);
|
|
552
605
|
this.sessionInfo = sessionInfo;
|
|
553
|
-
|
|
554
|
-
// Send session info immediately if the chat is already maximized
|
|
555
606
|
if (this.iframe?.contentWindow && this.iframe.style.display !== "none") {
|
|
556
607
|
this.iframe.contentWindow.postMessage({ type: 'setSessionInfo', sessionInfo: this.sessionInfo, instanceId: this.instanceId }, this.targetOrigin);
|
|
557
608
|
}
|
|
@@ -565,78 +616,55 @@
|
|
|
565
616
|
return chatContainer;
|
|
566
617
|
}
|
|
567
618
|
|
|
619
|
+
maximizeWithText(text) {
|
|
620
|
+
this.showMaximized(true, text);
|
|
621
|
+
}
|
|
622
|
+
|
|
568
623
|
buildIframeUrl(baseIframeUrl, params = {}) {
|
|
569
624
|
const urlParams = new URLSearchParams();
|
|
570
|
-
|
|
571
|
-
if (params.isPreview) {
|
|
572
|
-
urlParams.set('isPreview', 'true');
|
|
573
|
-
}
|
|
574
|
-
|
|
625
|
+
if (params.isPreview) urlParams.set('isPreview', 'true');
|
|
575
626
|
if (params.mode === 'ContactForm' || params.mode === 'PartnerOffers' || params.mode === 'Chat') {
|
|
576
627
|
urlParams.set('mode', params.mode);
|
|
577
628
|
}
|
|
578
|
-
|
|
579
|
-
if (params.
|
|
580
|
-
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
if (params.conversationId) {
|
|
584
|
-
urlParams.set('conversationId', params.conversationId);
|
|
585
|
-
}
|
|
629
|
+
if (params.locale) urlParams.set('locale', params.locale);
|
|
630
|
+
if (params.conversationId) urlParams.set('conversationId', params.conversationId);
|
|
631
|
+
if (params.instanceId) urlParams.set('instanceId', params.instanceId);
|
|
586
632
|
|
|
587
633
|
for (const [key, value] of Object.entries(params)) {
|
|
588
|
-
if (
|
|
634
|
+
if (!['mode', 'isPreview', 'conversationId', 'instanceId', 'userToken'].includes(key) && value !== null && value !== undefined) {
|
|
589
635
|
urlParams.set(key, value);
|
|
590
636
|
}
|
|
591
637
|
}
|
|
592
|
-
|
|
593
638
|
return `${baseIframeUrl}?${urlParams.toString()}`;
|
|
594
639
|
}
|
|
595
640
|
|
|
596
641
|
waitForIframeLoad(iframe, timeout = 10000) {
|
|
597
642
|
return new Promise((resolve) => {
|
|
598
|
-
// Set up a timeout to avoid waiting indefinitely
|
|
599
643
|
const timeoutId = setTimeout(() => {
|
|
600
644
|
console.warn('EmbeddedChat: Iframe load timeout, proceeding with initialization.');
|
|
601
645
|
resolve();
|
|
602
646
|
}, timeout);
|
|
603
647
|
|
|
604
|
-
// Add the load event listener
|
|
605
648
|
iframe.addEventListener('load', () => {
|
|
606
|
-
clearTimeout(timeoutId);
|
|
649
|
+
clearTimeout(timeoutId);
|
|
607
650
|
resolve();
|
|
608
|
-
}, { once: true });
|
|
651
|
+
}, { once: true });
|
|
609
652
|
});
|
|
610
653
|
}
|
|
611
654
|
|
|
612
655
|
async postAuthToIframes() {
|
|
613
|
-
|
|
614
|
-
if (typeof this.userTokenProvider !== 'function') {
|
|
615
|
-
console.warn('[EmbeddedChat] No userTokenProvider function provided');
|
|
616
|
-
return;
|
|
617
|
-
}
|
|
618
|
-
|
|
656
|
+
if (typeof this.userTokenProvider !== 'function') return;
|
|
619
657
|
try {
|
|
620
658
|
const userToken = await this.userTokenProvider();
|
|
621
|
-
|
|
622
|
-
if (!userToken) {
|
|
623
|
-
console.warn('[EmbeddedChat] userTokenProvider returned null/empty token');
|
|
624
|
-
return;
|
|
625
|
-
}
|
|
626
|
-
|
|
659
|
+
if (!userToken) return;
|
|
627
660
|
if (this.iframe?.contentWindow) {
|
|
628
|
-
console.log('[EmbeddedChat] Sending auth message to iframe with targetOrigin:', this.targetOrigin);
|
|
629
661
|
this.iframe.contentWindow.postMessage({
|
|
630
662
|
type: 'auth',
|
|
631
663
|
userToken: userToken,
|
|
632
664
|
chatId: this.chatId,
|
|
633
665
|
instanceId: this.instanceId
|
|
634
666
|
}, this.targetOrigin);
|
|
635
|
-
console.log('[EmbeddedChat] Auth message sent successfully');
|
|
636
|
-
} else {
|
|
637
|
-
console.error('[EmbeddedChat] iframe.contentWindow is not available');
|
|
638
667
|
}
|
|
639
|
-
// No longer send auth to minimizedIframe
|
|
640
668
|
} catch (err) {
|
|
641
669
|
console.error('[EmbeddedChat] Failed to get user token:', err);
|
|
642
670
|
}
|
|
@@ -647,9 +675,7 @@
|
|
|
647
675
|
|
|
648
676
|
console.log(`[EmbeddedChat] Setting mode to ${newMode}`, options);
|
|
649
677
|
this.mode = newMode;
|
|
650
|
-
if (options.chatId)
|
|
651
|
-
this.chatId = options.chatId;
|
|
652
|
-
}
|
|
678
|
+
if (options.chatId) this.chatId = options.chatId;
|
|
653
679
|
this.options = { ...this.options, ...options };
|
|
654
680
|
const transitionStyle = this.enableAnimation ? 'transition: height 0.3s ease, opacity 0.3s ease;' : '';
|
|
655
681
|
if (this.mode === 'ContactForm' || this.mode === 'PartnerOffers') {
|
|
@@ -659,7 +685,9 @@
|
|
|
659
685
|
} else {
|
|
660
686
|
this.positionStyle = this.position === 'in-place' ?
|
|
661
687
|
`position: relative; width:100%; height:${this.height}px; ${transitionStyle}` :
|
|
662
|
-
|
|
688
|
+
(this.theme === 'MinimalInput' ?
|
|
689
|
+
`position: fixed; left: 0; right: 0; margin-left: auto; margin-right: auto; bottom: ${this.marginBottom}px; width: ${this.width}px; z-index: 100000; max-width:90vw; max-height: 90vh; ${transitionStyle}` :
|
|
690
|
+
`position: fixed; right: 1em; bottom: ${this.marginBottom}px; width: ${this.width}px; z-index: 100000; max-width:90vw; max-height: 90vh; ${transitionStyle}`);
|
|
663
691
|
if (this.position === 'in-place') {
|
|
664
692
|
this.containerDiv.style.position = 'relative';
|
|
665
693
|
this.containerDiv.style.width = '100%';
|
|
@@ -684,4 +712,3 @@ export function initOffers(options = {}) {
|
|
|
684
712
|
const mergedOptions = { ...options, mode: 'PartnerOffers', height: options.height || 500 };
|
|
685
713
|
return new EmbeddedChat(options.container, chatId, mergedOptions);
|
|
686
714
|
}
|
|
687
|
-
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "embeddedaichatux",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "A lightweight and customizable embedded AI chat UI component that seamlessly integrates into web applications, offering minimized and expanded views, with iframe-based content rendering.",
|
|
5
5
|
"main": "EmbeddedChat.js",
|
|
6
6
|
"scripts": {
|