embeddedaichatux 1.3.1 → 1.4.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 +121 -44
- package/package.json +1 -1
package/EmbeddedChat.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
class EmbeddedChat {
|
|
1
|
+
class EmbeddedChat {
|
|
3
2
|
constructor(containerDiv, chatId, options) {
|
|
4
3
|
if (!containerDiv) {
|
|
5
4
|
containerDiv = this.createChatContainer();
|
|
@@ -8,70 +7,146 @@ class EmbeddedChat {
|
|
|
8
7
|
this.chatId = chatId;
|
|
9
8
|
this.options = options || {};
|
|
10
9
|
this.isPreview = this.options.isPreview || false;
|
|
10
|
+
this.locale = options.locale || 'en';
|
|
11
11
|
this.previewParam = this.isPreview ? "?isPreview=true" : "";
|
|
12
12
|
this.serverUrl = this.options.serverUrl || 'https://embedgpt.chat/';
|
|
13
|
-
this.
|
|
13
|
+
this.height = options.height || 600; // Default height
|
|
14
|
+
this.width = options.width || 300; // Default width
|
|
15
|
+
this.enableAnimation = options.enableAnimation !== false; // Default to true if not provided
|
|
16
|
+
this.minimizedHeight = `${this.height * 0.3}px`; // 30% of the full height
|
|
17
|
+
this.mouseInsideChat = false;
|
|
18
|
+
|
|
19
|
+
// Determine transition styles
|
|
20
|
+
const transitionStyle = this.enableAnimation ? 'transition: height 0.3s ease, opacity 0.3s ease;' : '';
|
|
21
|
+
|
|
22
|
+
this.positionStyle = this.containerDiv.dataset.position === 'in-place' ?
|
|
23
|
+
`width:100%; height:${this.height}px; ${transitionStyle}` :
|
|
24
|
+
`position: fixed; right: 0; bottom: 0; width: ${this.width}px; height: ${this.height}px; z-index: 100000; ${transitionStyle}`;
|
|
14
25
|
this.mode = options.mode || 'Chat'; // default to 'chat' if mode isn't provided
|
|
26
|
+
this.minimizeOnScroll = false; // Default to false
|
|
15
27
|
if (this.mode === 'ContactForm') {
|
|
16
28
|
// Adjust position style for contact form if mode is 'ContactForm'
|
|
17
|
-
this.positionStyle =
|
|
18
|
-
this.containerDiv.style.height =
|
|
29
|
+
this.positionStyle = `width:100%; height:${this.height}px; ${transitionStyle}`;
|
|
30
|
+
this.containerDiv.style.height = `${this.height}px`;
|
|
19
31
|
}
|
|
32
|
+
this.sessionInfo = options.sessionInfo || null;
|
|
20
33
|
this.init();
|
|
21
34
|
}
|
|
22
35
|
|
|
23
|
-
init() {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
36
|
+
init() {
|
|
37
|
+
const cleanedServerUrl = this.serverUrl.endsWith('/') ? this.serverUrl.slice(0, -1) : this.serverUrl;
|
|
38
|
+
const baseIframeUrl = `${cleanedServerUrl}/ChatUX/${this.chatId}`;
|
|
39
|
+
const minimizedPositionStyle = `position: fixed; right: 0; bottom: 0; width: ${this.width}px; height: ${this.minimizedHeight}; z-index: 100000; ${this.enableAnimation ? 'transition: height 0.3s ease, opacity 0.3s ease;' : ''}`;
|
|
27
40
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
41
|
+
const iframeHtml = `
|
|
42
|
+
<iframe id="embedded-chat" style="${this.positionStyle}; display: none; border:none; overflow:hidden;" frameborder="0" sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="${this.buildIframeUrl(baseIframeUrl, { isPreview: this.isPreview, mode: this.mode, locale: this.locale })}"></iframe>
|
|
43
|
+
<iframe id="embedded-chat-minimized" style="${minimizedPositionStyle}; display: none; border:none; overflow:hidden;" frameborder="0" sandbox="allow-same-origin allow-scripts allow-popups allow-forms" src="${this.buildIframeUrl(baseIframeUrl, { isPreview: this.isPreview, isMinimized: true, locale: this.locale })}"></iframe>
|
|
44
|
+
`;
|
|
32
45
|
|
|
33
46
|
this.containerDiv.innerHTML = iframeHtml;
|
|
34
47
|
this.iframe = this.containerDiv.querySelector("#embedded-chat");
|
|
35
48
|
this.minimizedIframe = this.containerDiv.querySelector("#embedded-chat-minimized");
|
|
36
49
|
|
|
50
|
+
// Add event listeners to track mouse position
|
|
51
|
+
this.iframe.addEventListener("mouseenter", () => { this.mouseInsideChat = true; });
|
|
52
|
+
this.iframe.addEventListener("mouseleave", () => { this.mouseInsideChat = false; });
|
|
53
|
+
this.minimizedIframe.addEventListener("mouseenter", () => { this.mouseInsideChat = true; });
|
|
54
|
+
this.minimizedIframe.addEventListener("mouseleave", () => { this.mouseInsideChat = false; });
|
|
55
|
+
|
|
37
56
|
window.addEventListener("message", (e) => {
|
|
38
|
-
|
|
39
|
-
|
|
57
|
+
this.handleMessage(e);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
window.addEventListener("scroll", () => {
|
|
61
|
+
if (this.minimizeOnScroll && !this.mouseInsideChat) {
|
|
62
|
+
this.minimizeOnScrollAction();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
handleMessage(e) {
|
|
68
|
+
if (typeof e.data === "object" && (!e.data.chatId || e.data.chatId === this.chatId)) {
|
|
69
|
+
if (e.data.type === "setMinimizeOnScroll") {
|
|
70
|
+
this.minimizeOnScroll = e.data.value === "true";
|
|
71
|
+
}
|
|
72
|
+
if (e.data.message) {
|
|
40
73
|
if (e.data.message === "minimize") {
|
|
41
74
|
if (this.mode !== 'ContactForm') {
|
|
42
|
-
|
|
43
|
-
this.iframe.style.display = "none";
|
|
44
|
-
this.minimizedIframe.style.display = "block";
|
|
75
|
+
this.animateMinimize();
|
|
45
76
|
}
|
|
46
77
|
} else if (e.data.message === "show" || e.data.message === "maximize") {
|
|
47
|
-
this.
|
|
48
|
-
this.minimizedIframe.style.display = "none";
|
|
49
|
-
// Check if the data has a scale property
|
|
50
|
-
if (e.data.scale) {
|
|
51
|
-
if (this.mode !== 'ContactForm') {
|
|
52
|
-
// No scaling support for ContactForm
|
|
53
|
-
|
|
54
|
-
// Resize the iframe according to the scale factor
|
|
55
|
-
this.iframe.style.transform = `scale(${e.data.scale})`;
|
|
56
|
-
this.iframe.style.transformOrigin = "bottom right";
|
|
57
|
-
}
|
|
58
|
-
}
|
|
78
|
+
this.showMaximized();
|
|
59
79
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (
|
|
64
|
-
this.
|
|
65
|
-
this.minimizedIframe.style.display = "block";
|
|
66
|
-
} else if (e.data === "show" || e.data === "maximize") {
|
|
67
|
-
this.iframe.style.display = "block";
|
|
68
|
-
this.minimizedIframe.style.display = "none";
|
|
80
|
+
if (e.data.scale) {
|
|
81
|
+
this.applyScale(e.data.scale);
|
|
82
|
+
}
|
|
83
|
+
if (this.sessionInfo !== null) {
|
|
84
|
+
this.setSessionInfo(this.sessionInfo);
|
|
69
85
|
}
|
|
70
86
|
}
|
|
71
|
-
})
|
|
87
|
+
} else if (typeof e.data === "string") {
|
|
88
|
+
if (e.data === "minimize") {
|
|
89
|
+
this.animateMinimize();
|
|
90
|
+
} else if (e.data === "show" || e.data === "maximize") {
|
|
91
|
+
this.showMaximized();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
animateMinimize() {
|
|
97
|
+
if (this.mode !== 'ContactForm') {
|
|
98
|
+
this.iframe.style.height = this.minimizedHeight;
|
|
99
|
+
this.iframe.style.opacity = '0'; // Full transparency at the end
|
|
100
|
+
setTimeout(() => {
|
|
101
|
+
this.iframe.style.display = "none";
|
|
102
|
+
this.iframe.style.opacity = '1'; // Reset opacity to 1 for next time
|
|
103
|
+
this.minimizedIframe.style.display = "block";
|
|
104
|
+
this.minimizedIframe.style.height = this.minimizedHeight;
|
|
105
|
+
this.minimizedIframe.style.opacity = '1'; // Reset opacity to 1
|
|
106
|
+
}, this.enableAnimation ? 300 : 0); // Match the transition duration
|
|
107
|
+
}
|
|
72
108
|
}
|
|
73
109
|
|
|
110
|
+
showMaximized() {
|
|
111
|
+
this.minimizedIframe.style.display = "none";
|
|
112
|
+
this.minimizedIframe.style.height = `${this.height}px`;
|
|
113
|
+
this.minimizedIframe.style.opacity = ''; // Reset opacity to unset
|
|
114
|
+
this.iframe.style.display = "block";
|
|
115
|
+
this.iframe.style.height = `${this.height}px`;
|
|
116
|
+
this.iframe.style.opacity = '1';
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
applyScale(scale) {
|
|
120
|
+
if (this.mode !== 'ContactForm') {
|
|
121
|
+
this.iframe.style.transform = `scale(${scale})`;
|
|
122
|
+
this.iframe.style.transformOrigin = "bottom right";
|
|
123
|
+
this.minimizedIframe.style.transform = `scale(${scale})`;
|
|
124
|
+
this.minimizedIframe.style.transformOrigin = "bottom right";
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
minimizeOnScrollAction() {
|
|
129
|
+
if (this.mode !== 'ContactForm' && this.iframe.style.display !== "none") {
|
|
130
|
+
this.animateMinimize();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
74
133
|
|
|
134
|
+
setSessionInfo(sessionInfo) {
|
|
135
|
+
console.log('setSessionInfo called with sessionInfo:', sessionInfo);
|
|
136
|
+
|
|
137
|
+
this.sessionInfo = sessionInfo;
|
|
138
|
+
|
|
139
|
+
const iframe = this.containerDiv.querySelector("#embedded-chat");
|
|
140
|
+
|
|
141
|
+
const postMessage = () => {
|
|
142
|
+
console.log('Posting message to iframe:', { type: 'setSessionInfo', sessionInfo: sessionInfo });
|
|
143
|
+
iframe.contentWindow.postMessage({ type: 'setSessionInfo', sessionInfo: sessionInfo }, "*");
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
if (iframe.style.display !== "none") {
|
|
147
|
+
postMessage();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
75
150
|
|
|
76
151
|
createChatContainer() {
|
|
77
152
|
const chatContainer = document.createElement('div');
|
|
@@ -84,7 +159,6 @@ init() {
|
|
|
84
159
|
buildIframeUrl(baseIframeUrl, params = {}) {
|
|
85
160
|
const urlParams = new URLSearchParams(params);
|
|
86
161
|
|
|
87
|
-
// Add parameters as needed, based on values in the params object
|
|
88
162
|
if (params.isPreview) {
|
|
89
163
|
urlParams.set('isPreview', 'true');
|
|
90
164
|
}
|
|
@@ -93,9 +167,12 @@ init() {
|
|
|
93
167
|
urlParams.set('mode', 'ContactForm');
|
|
94
168
|
}
|
|
95
169
|
|
|
96
|
-
|
|
170
|
+
if (params.locale) {
|
|
171
|
+
urlParams.set('locale', params.locale);
|
|
172
|
+
}
|
|
173
|
+
|
|
97
174
|
for (const [key, value] of Object.entries(params)) {
|
|
98
|
-
if (key !== 'mode' && key !== 'isPreview') {
|
|
175
|
+
if (key !== 'mode' && key !== 'isPreview') {
|
|
99
176
|
urlParams.set(key, value);
|
|
100
177
|
}
|
|
101
178
|
}
|
|
@@ -109,6 +186,6 @@ export function initEmbeddedChat(containerDiv, chatId, options) {
|
|
|
109
186
|
}
|
|
110
187
|
|
|
111
188
|
export function initContactForm(containerDiv, chatId, options) {
|
|
112
|
-
const clonedOptions = { ...options, mode: 'ContactForm' };
|
|
189
|
+
const clonedOptions = { ...options, mode: 'ContactForm' };
|
|
113
190
|
return new EmbeddedChat(containerDiv, chatId, clonedOptions);
|
|
114
191
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "embeddedaichatux",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.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": {
|