embeddedaichatux 1.3.2 → 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 +96 -48
- 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();
|
|
@@ -11,12 +10,24 @@ class EmbeddedChat {
|
|
|
11
10
|
this.locale = options.locale || 'en';
|
|
12
11
|
this.previewParam = this.isPreview ? "?isPreview=true" : "";
|
|
13
12
|
this.serverUrl = this.options.serverUrl || 'https://embedgpt.chat/';
|
|
14
|
-
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}`;
|
|
15
25
|
this.mode = options.mode || 'Chat'; // default to 'chat' if mode isn't provided
|
|
26
|
+
this.minimizeOnScroll = false; // Default to false
|
|
16
27
|
if (this.mode === 'ContactForm') {
|
|
17
28
|
// Adjust position style for contact form if mode is 'ContactForm'
|
|
18
|
-
this.positionStyle =
|
|
19
|
-
this.containerDiv.style.height =
|
|
29
|
+
this.positionStyle = `width:100%; height:${this.height}px; ${transitionStyle}`;
|
|
30
|
+
this.containerDiv.style.height = `${this.height}px`;
|
|
20
31
|
}
|
|
21
32
|
this.sessionInfo = options.sessionInfo || null;
|
|
22
33
|
this.init();
|
|
@@ -25,74 +36,113 @@ class EmbeddedChat {
|
|
|
25
36
|
init() {
|
|
26
37
|
const cleanedServerUrl = this.serverUrl.endsWith('/') ? this.serverUrl.slice(0, -1) : this.serverUrl;
|
|
27
38
|
const baseIframeUrl = `${cleanedServerUrl}/ChatUX/${this.chatId}`;
|
|
28
|
-
const minimizedPositionStyle =
|
|
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;' : ''}`;
|
|
29
40
|
|
|
30
41
|
const iframeHtml = `
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
+
`;
|
|
34
45
|
|
|
35
46
|
this.containerDiv.innerHTML = iframeHtml;
|
|
36
47
|
this.iframe = this.containerDiv.querySelector("#embedded-chat");
|
|
37
48
|
this.minimizedIframe = this.containerDiv.querySelector("#embedded-chat-minimized");
|
|
38
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
|
+
|
|
39
56
|
window.addEventListener("message", (e) => {
|
|
40
|
-
|
|
41
|
-
|
|
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) {
|
|
42
73
|
if (e.data.message === "minimize") {
|
|
43
74
|
if (this.mode !== 'ContactForm') {
|
|
44
|
-
|
|
45
|
-
this.iframe.style.display = "none";
|
|
46
|
-
this.minimizedIframe.style.display = "block";
|
|
75
|
+
this.animateMinimize();
|
|
47
76
|
}
|
|
48
77
|
} else if (e.data.message === "show" || e.data.message === "maximize") {
|
|
49
|
-
this.
|
|
50
|
-
this.minimizedIframe.style.display = "none";
|
|
51
|
-
// Check if the data has a scale property
|
|
52
|
-
if (e.data.scale) {
|
|
53
|
-
if (this.mode !== 'ContactForm') {
|
|
54
|
-
// No scaling support for ContactForm
|
|
55
|
-
|
|
56
|
-
// Resize the iframe according to the scale factor
|
|
57
|
-
this.iframe.style.transform = `scale(${e.data.scale})`;
|
|
58
|
-
this.iframe.style.transformOrigin = "bottom right";
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// Send sessionInfo if available
|
|
62
|
-
if (this.sessionInfo !== null) {
|
|
63
|
-
this.setSessionInfo(this.sessionInfo);
|
|
64
|
-
}
|
|
78
|
+
this.showMaximized();
|
|
65
79
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (
|
|
70
|
-
this.
|
|
71
|
-
this.minimizedIframe.style.display = "block";
|
|
72
|
-
} else if (e.data === "show" || e.data === "maximize") {
|
|
73
|
-
this.iframe.style.display = "block";
|
|
74
|
-
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);
|
|
75
85
|
}
|
|
76
86
|
}
|
|
77
|
-
})
|
|
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
|
+
}
|
|
108
|
+
}
|
|
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
|
+
}
|
|
78
132
|
}
|
|
79
133
|
|
|
80
134
|
setSessionInfo(sessionInfo) {
|
|
81
135
|
console.log('setSessionInfo called with sessionInfo:', sessionInfo);
|
|
82
136
|
|
|
83
|
-
// Store the new sessionInfo
|
|
84
137
|
this.sessionInfo = sessionInfo;
|
|
85
138
|
|
|
86
|
-
// Obtain the iframe element
|
|
87
139
|
const iframe = this.containerDiv.querySelector("#embedded-chat");
|
|
88
140
|
|
|
89
|
-
// Function to post the message with a structured object
|
|
90
141
|
const postMessage = () => {
|
|
91
142
|
console.log('Posting message to iframe:', { type: 'setSessionInfo', sessionInfo: sessionInfo });
|
|
92
143
|
iframe.contentWindow.postMessage({ type: 'setSessionInfo', sessionInfo: sessionInfo }, "*");
|
|
93
144
|
};
|
|
94
145
|
|
|
95
|
-
// If the iframe is visible, post the message
|
|
96
146
|
if (iframe.style.display !== "none") {
|
|
97
147
|
postMessage();
|
|
98
148
|
}
|
|
@@ -109,7 +159,6 @@ class EmbeddedChat {
|
|
|
109
159
|
buildIframeUrl(baseIframeUrl, params = {}) {
|
|
110
160
|
const urlParams = new URLSearchParams(params);
|
|
111
161
|
|
|
112
|
-
// Add parameters as needed, based on values in the params object
|
|
113
162
|
if (params.isPreview) {
|
|
114
163
|
urlParams.set('isPreview', 'true');
|
|
115
164
|
}
|
|
@@ -122,9 +171,8 @@ class EmbeddedChat {
|
|
|
122
171
|
urlParams.set('locale', params.locale);
|
|
123
172
|
}
|
|
124
173
|
|
|
125
|
-
// Handle other parameters directly from the params object
|
|
126
174
|
for (const [key, value] of Object.entries(params)) {
|
|
127
|
-
if (key !== 'mode' && key !== 'isPreview') {
|
|
175
|
+
if (key !== 'mode' && key !== 'isPreview') {
|
|
128
176
|
urlParams.set(key, value);
|
|
129
177
|
}
|
|
130
178
|
}
|
|
@@ -138,6 +186,6 @@ export function initEmbeddedChat(containerDiv, chatId, options) {
|
|
|
138
186
|
}
|
|
139
187
|
|
|
140
188
|
export function initContactForm(containerDiv, chatId, options) {
|
|
141
|
-
const clonedOptions = { ...options, mode: 'ContactForm' };
|
|
189
|
+
const clonedOptions = { ...options, mode: 'ContactForm' };
|
|
142
190
|
return new EmbeddedChat(containerDiv, chatId, clonedOptions);
|
|
143
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": {
|