embeddedaichatux 2.2.1 → 2.3.0
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 +87 -43
- package/package.json +1 -1
package/EmbeddedChat.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
class EmbeddedChat {
|
|
2
2
|
static instanceCounter = 0;
|
|
3
3
|
|
|
4
4
|
constructor(containerDiv, chatId, options) {
|
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
if (!containerDiv) {
|
|
9
9
|
containerDiv = this.createChatContainer();
|
|
10
|
+
this.createdContainer = true;
|
|
11
|
+
} else {
|
|
12
|
+
this.createdContainer = false;
|
|
10
13
|
}
|
|
11
14
|
this.containerDiv = containerDiv;
|
|
12
15
|
this.chatId = chatId;
|
|
@@ -55,6 +58,13 @@
|
|
|
55
58
|
this.init();
|
|
56
59
|
}
|
|
57
60
|
|
|
61
|
+
queueDOMUpdate(fn) {
|
|
62
|
+
requestAnimationFrame(() => {
|
|
63
|
+
if (this.isDestroyed) return;
|
|
64
|
+
fn();
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
58
68
|
isSafari() {
|
|
59
69
|
const ua = navigator.userAgent.toLowerCase();
|
|
60
70
|
return ua.indexOf('safari') != -1 && ua.indexOf('chrome') == -1;
|
|
@@ -92,6 +102,8 @@
|
|
|
92
102
|
}
|
|
93
103
|
|
|
94
104
|
async updateIframes() {
|
|
105
|
+
if (this.isDestroyed) return;
|
|
106
|
+
|
|
95
107
|
const cleanedServerUrl = this.serverUrl.endsWith('/')
|
|
96
108
|
? this.serverUrl.slice(0, -1)
|
|
97
109
|
: this.serverUrl;
|
|
@@ -153,11 +165,13 @@
|
|
|
153
165
|
if (this.iframe) {
|
|
154
166
|
await this.waitForIframeLoad(this.iframe);
|
|
155
167
|
}
|
|
168
|
+
if (this.isDestroyed) return;
|
|
156
169
|
|
|
157
170
|
this.addIframeEventListeners();
|
|
158
171
|
|
|
159
172
|
// Send auth to iframes after load
|
|
160
173
|
await this.postAuthToIframes();
|
|
174
|
+
if (this.isDestroyed) return;
|
|
161
175
|
|
|
162
176
|
// Restore ContactForm logic
|
|
163
177
|
if (this.mode === 'ContactForm' || this.mode === 'PartnerOffers') {
|
|
@@ -187,32 +201,34 @@
|
|
|
187
201
|
addWindowEventListeners() {
|
|
188
202
|
if (this.windowListenersAdded) return;
|
|
189
203
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
204
|
+
this.listeners = [
|
|
205
|
+
{ type: "message", fn: (e) => {
|
|
206
|
+
if (this.targetOrigin !== "*" && e.origin !== this.targetOrigin) return;
|
|
207
|
+
this.handleMessage(e);
|
|
208
|
+
}},
|
|
209
|
+
{ type: "scroll", fn: () => {
|
|
210
|
+
if (this.minimizeOnScroll && !this.mouseInsideChat) {
|
|
211
|
+
this.queueDOMUpdate(() => this.minimizeOnScrollAction());
|
|
212
|
+
}
|
|
213
|
+
}},
|
|
214
|
+
{ type: "resize", fn: () => this.queueDOMUpdate(() => this.postResizeMessage()) }
|
|
215
|
+
];
|
|
200
216
|
|
|
201
|
-
|
|
202
|
-
this.postResizeMessage();
|
|
203
|
-
};
|
|
217
|
+
this.listeners.forEach(l => window.addEventListener(l.type, l.fn));
|
|
204
218
|
|
|
219
|
+
const loadFn = () => this.queueDOMUpdate(() => this.postResizeMessage());
|
|
205
220
|
if (document.readyState === 'complete') {
|
|
206
|
-
|
|
221
|
+
loadFn();
|
|
207
222
|
} else {
|
|
208
|
-
|
|
223
|
+
this.listeners.push({ type: "load", fn: loadFn });
|
|
224
|
+
window.addEventListener("load", loadFn);
|
|
209
225
|
}
|
|
210
226
|
|
|
211
|
-
window.addEventListener("resize", handleResizeTrigger);
|
|
212
227
|
this.windowListenersAdded = true;
|
|
213
228
|
}
|
|
214
229
|
|
|
215
230
|
postResizeMessage() {
|
|
231
|
+
if (this.isDestroyed) return;
|
|
216
232
|
if (this.iframe?.contentWindow) {
|
|
217
233
|
this.iframe.contentWindow.postMessage({
|
|
218
234
|
message: "resize",
|
|
@@ -262,37 +278,36 @@
|
|
|
262
278
|
if (msg === "updateMinimizedSize") {
|
|
263
279
|
const h = data.minimizedHeight || data.height;
|
|
264
280
|
const w = data.minimizedWidth || data.width;
|
|
265
|
-
this.updateMinimizedSize(h, w);
|
|
281
|
+
this.queueDOMUpdate(() => this.updateMinimizedSize(h, w));
|
|
266
282
|
return;
|
|
267
283
|
}
|
|
268
284
|
|
|
269
285
|
if (msg === "collapseMinimalInput") {
|
|
270
|
-
|
|
271
|
-
this.minimizedIframe
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
286
|
+
this.queueDOMUpdate(() => {
|
|
287
|
+
if (this.minimizedIframe) {
|
|
288
|
+
Object.assign(this.minimizedIframe.style, {
|
|
289
|
+
width: '80px', height: '80px', left: 'auto', right: '0',
|
|
290
|
+
marginLeft: '0', marginRight: '0', pointerEvents: 'auto'
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
});
|
|
279
294
|
return;
|
|
280
295
|
}
|
|
281
296
|
|
|
282
297
|
if (msg === "restoreMinimalInput") {
|
|
283
|
-
|
|
284
|
-
this.minimizedIframe
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
298
|
+
this.queueDOMUpdate(() => {
|
|
299
|
+
if (this.minimizedIframe) {
|
|
300
|
+
Object.assign(this.minimizedIframe.style, {
|
|
301
|
+
width: '100vw', maxWidth: `${Math.min(300, this.width) + 40}px`,
|
|
302
|
+
height: this.theme === 'MinimalInput' ? "75px" : this.minimizedHeight,
|
|
303
|
+
left: '0', right: '0', marginLeft: 'auto', marginRight: 'auto',
|
|
304
|
+
pointerEvents: 'auto'
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
if (this.theme === 'MinimalInput' && this.position !== 'in-place') {
|
|
308
|
+
this.containerDiv.style.pointerEvents = 'none';
|
|
309
|
+
}
|
|
310
|
+
});
|
|
296
311
|
return;
|
|
297
312
|
}
|
|
298
313
|
|
|
@@ -310,18 +325,18 @@
|
|
|
310
325
|
if (data.theme) updates.theme = data.theme;
|
|
311
326
|
|
|
312
327
|
if (Object.keys(updates).length > 0) {
|
|
313
|
-
this.applyIframeUpdates(updates);
|
|
328
|
+
this.queueDOMUpdate(() => this.applyIframeUpdates(updates));
|
|
314
329
|
}
|
|
315
330
|
|
|
316
331
|
if (msg === "minimize") {
|
|
317
332
|
if (typeof this.options.onMinimize === 'function') {
|
|
318
333
|
this.options.onMinimize();
|
|
319
334
|
} else if (this.mode !== 'ContactForm' && this.mode !== 'PartnerOffers') {
|
|
320
|
-
this.animateMinimize();
|
|
335
|
+
this.queueDOMUpdate(() => this.animateMinimize());
|
|
321
336
|
}
|
|
322
337
|
} else if (msg === "show" || msg === "maximize") {
|
|
323
338
|
const animate = data.animate === true;
|
|
324
|
-
this.showMaximized(animate, data.initialMessage);
|
|
339
|
+
this.queueDOMUpdate(() => this.showMaximized(animate, data.initialMessage));
|
|
325
340
|
} else if (msg === "navigate" && data.url) {
|
|
326
341
|
window.location.href = data.url;
|
|
327
342
|
} else if (data.type === "switchToChat" || msg === "switchToChat") {
|
|
@@ -344,10 +359,12 @@
|
|
|
344
359
|
}
|
|
345
360
|
|
|
346
361
|
animateMinimize() {
|
|
362
|
+
if (this.isDestroyed) return;
|
|
347
363
|
if (this.mode !== 'ContactForm' && this.mode !== 'PartnerOffers') {
|
|
348
364
|
this.iframe.style.height = this.minimizedHeight;
|
|
349
365
|
this.iframe.style.opacity = '0';
|
|
350
366
|
setTimeout(() => {
|
|
367
|
+
if (this.isDestroyed) return;
|
|
351
368
|
this.iframe.style.display = "none";
|
|
352
369
|
this.iframe.style.opacity = '1';
|
|
353
370
|
this.minimizedIframe.style.display = "block";
|
|
@@ -362,6 +379,7 @@
|
|
|
362
379
|
}
|
|
363
380
|
|
|
364
381
|
updateMinimizedSize(contentHeight, contentWidth) {
|
|
382
|
+
if (this.isDestroyed) return;
|
|
365
383
|
if (this.mode === 'ContactForm' || this.mode === 'PartnerOffers') return;
|
|
366
384
|
|
|
367
385
|
this.hasMeasuredSize = true;
|
|
@@ -418,6 +436,7 @@
|
|
|
418
436
|
}
|
|
419
437
|
|
|
420
438
|
applyIframeUpdates({ locale, width, height, marginBottom, scale, theme } = {}) {
|
|
439
|
+
if (this.isDestroyed) return;
|
|
421
440
|
if (theme && typeof theme === 'string' && theme !== this.theme) {
|
|
422
441
|
this.theme = theme;
|
|
423
442
|
console.log(`Theme updated to: ${this.theme}`);
|
|
@@ -542,6 +561,7 @@
|
|
|
542
561
|
}
|
|
543
562
|
|
|
544
563
|
showMaximized(animate = false, initialMessage = null) {
|
|
564
|
+
if (this.isDestroyed) return;
|
|
545
565
|
const schedulePostMessage = () => {
|
|
546
566
|
if (this.iframe.contentWindow) {
|
|
547
567
|
this.iframe.contentWindow.postMessage({
|
|
@@ -552,6 +572,7 @@
|
|
|
552
572
|
}, this.targetOrigin);
|
|
553
573
|
} else {
|
|
554
574
|
setTimeout(() => {
|
|
575
|
+
if (this.isDestroyed) return;
|
|
555
576
|
if (this.iframe.contentWindow) {
|
|
556
577
|
this.iframe.contentWindow.postMessage({
|
|
557
578
|
message: "show",
|
|
@@ -596,6 +617,7 @@
|
|
|
596
617
|
}
|
|
597
618
|
|
|
598
619
|
minimizeOnScrollAction() {
|
|
620
|
+
if (this.isDestroyed) return;
|
|
599
621
|
if (this.mode !== 'ContactForm' && this.mode !== 'PartnerOffers' && this.iframe.style.display !== "none") {
|
|
600
622
|
this.animateMinimize();
|
|
601
623
|
}
|
|
@@ -653,6 +675,7 @@
|
|
|
653
675
|
}
|
|
654
676
|
|
|
655
677
|
async postAuthToIframes() {
|
|
678
|
+
if (this.isDestroyed) return;
|
|
656
679
|
if (typeof this.userTokenProvider !== 'function') return;
|
|
657
680
|
try {
|
|
658
681
|
const userToken = await this.userTokenProvider();
|
|
@@ -696,6 +719,27 @@
|
|
|
696
719
|
}
|
|
697
720
|
this.updateIframes();
|
|
698
721
|
}
|
|
722
|
+
|
|
723
|
+
destroy() {
|
|
724
|
+
if (this.listeners) {
|
|
725
|
+
this.listeners.forEach(l => window.removeEventListener(l.type, l.fn));
|
|
726
|
+
this.listeners = null;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
this.windowListenersAdded = false;
|
|
730
|
+
this.isDestroyed = true;
|
|
731
|
+
|
|
732
|
+
if (this.containerDiv) {
|
|
733
|
+
if (this.createdContainer && this.containerDiv.parentNode) {
|
|
734
|
+
this.containerDiv.parentNode.removeChild(this.containerDiv);
|
|
735
|
+
} else if (!this.createdContainer) {
|
|
736
|
+
this.containerDiv.innerHTML = '';
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
this.iframe = null;
|
|
740
|
+
this.minimizedIframe = null;
|
|
741
|
+
this.containerDiv = null;
|
|
742
|
+
}
|
|
699
743
|
}
|
|
700
744
|
|
|
701
745
|
export function initEmbeddedChat(containerDiv, chatId, options) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "embeddedaichatux",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
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": {
|