embeddedaichatux 1.6.0 → 1.7.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 +141 -34
- package/package.json +5 -2
- package/AIChat.npm.csproj +0 -29
- package/AIChat.npm.csproj.user +0 -6
- package/AIChat.npm.sln +0 -25
- package/Properties/launchSettings.json +0 -37
package/EmbeddedChat.js
CHANGED
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
|
|
24
24
|
this.positionStyle = this.containerDiv.dataset.position === 'in-place' ?
|
|
25
25
|
`width:100%; height:${this.height}px; ${transitionStyle}` :
|
|
26
|
-
`position: fixed; right:
|
|
27
|
-
this.mode = options.mode || 'Chat'; // default to 'chat'
|
|
26
|
+
`position: fixed; right: 1em; bottom: 0; width: ${this.width}px; height: ${this.height}px; z-index: 100000; max-width:80%; ${transitionStyle}`;
|
|
27
|
+
this.mode = options.mode || 'Chat'; // default to 'chat'
|
|
28
28
|
this.minimizeOnScroll = false; // Default to false
|
|
29
29
|
if (this.mode === 'ContactForm') {
|
|
30
30
|
// Adjust position style for contact form if mode is 'ContactForm'
|
|
@@ -33,7 +33,6 @@
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
this.conversationId = this.getStoredConversationId();
|
|
36
|
-
|
|
37
36
|
this.sessionInfo = options.sessionInfo || null;
|
|
38
37
|
this.init();
|
|
39
38
|
}
|
|
@@ -65,7 +64,6 @@
|
|
|
65
64
|
const previousId = this.conversationId || 'null';
|
|
66
65
|
|
|
67
66
|
if (newConversationId !== previousId) {
|
|
68
|
-
// Separate block for changes to allow breakpoint placement
|
|
69
67
|
this.conversationId = newConversationId;
|
|
70
68
|
this.setStoredConversationId(newConversationId);
|
|
71
69
|
}
|
|
@@ -76,7 +74,7 @@
|
|
|
76
74
|
this.addEventListeners();
|
|
77
75
|
}
|
|
78
76
|
|
|
79
|
-
updateIframes() {
|
|
77
|
+
async updateIframes() {
|
|
80
78
|
const cleanedServerUrl = this.serverUrl.endsWith('/') ? this.serverUrl.slice(0, -1) : this.serverUrl;
|
|
81
79
|
const baseIframeUrl = `${cleanedServerUrl}/ChatUX/${this.chatId}`;
|
|
82
80
|
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;' : ''}`;
|
|
@@ -89,10 +87,11 @@
|
|
|
89
87
|
this.containerDiv.innerHTML = iframeHtml;
|
|
90
88
|
this.iframe = this.containerDiv.querySelector("#embedded-chat");
|
|
91
89
|
this.minimizedIframe = this.containerDiv.querySelector("#embedded-chat-minimized");
|
|
90
|
+
|
|
91
|
+
await this.waitForIframeLoad(this.iframe);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
addEventListeners() {
|
|
95
|
-
// Add event listeners to track mouse position
|
|
96
95
|
this.iframe.addEventListener("mouseenter", () => { this.mouseInsideChat = true; });
|
|
97
96
|
this.iframe.addEventListener("mouseleave", () => { this.mouseInsideChat = false; });
|
|
98
97
|
this.minimizedIframe.addEventListener("mouseenter", () => { this.mouseInsideChat = true; });
|
|
@@ -111,30 +110,47 @@
|
|
|
111
110
|
|
|
112
111
|
handleMessage(e) {
|
|
113
112
|
if (typeof e.data === "object" && (!e.data.chatId || e.data.chatId === this.chatId)) {
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
const updates = {};
|
|
114
|
+
|
|
115
|
+
if (e.data.type === "setMinimizeOnScroll" || e.data.minimizeOnScroll !== undefined) {
|
|
116
|
+
const minimizeValue = e.data.type === "setMinimizeOnScroll" ? e.data.value : e.data.minimizeOnScroll;
|
|
117
|
+
this.minimizeOnScroll = minimizeValue === true || minimizeValue === "true";
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Collect updates for locale, width, and scale
|
|
121
|
+
if (e.data.locale) {
|
|
122
|
+
updates.locale = e.data.locale;
|
|
116
123
|
}
|
|
124
|
+
if (e.data.width) {
|
|
125
|
+
updates.width = e.data.width;
|
|
126
|
+
}
|
|
127
|
+
if (e.data.scale) {
|
|
128
|
+
updates.scale = e.data.scale;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Apply iframe updates (locale, width, scale) in one go
|
|
132
|
+
if (Object.keys(updates).length > 0) {
|
|
133
|
+
this.applyIframeUpdates(updates);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Handle maximize/minimize
|
|
117
137
|
if (e.data.message) {
|
|
118
138
|
if (e.data.message === "minimize") {
|
|
119
139
|
if (this.mode !== 'ContactForm') {
|
|
120
140
|
this.animateMinimize();
|
|
121
141
|
}
|
|
122
142
|
} else if (e.data.message === "show" || e.data.message === "maximize") {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (e.data.scale) {
|
|
126
|
-
this.applyScale(e.data.scale);
|
|
127
|
-
}
|
|
128
|
-
if (this.sessionInfo !== null) {
|
|
129
|
-
this.setSessionInfo(this.sessionInfo);
|
|
143
|
+
const animate = e.data.animate === true;
|
|
144
|
+
this.showMaximized(animate);
|
|
130
145
|
}
|
|
131
146
|
}
|
|
132
147
|
|
|
133
|
-
//
|
|
148
|
+
// Handle conversationId update
|
|
134
149
|
if (e.data.conversationId) {
|
|
135
150
|
this.setConversationId(e.data.conversationId);
|
|
136
151
|
}
|
|
137
152
|
} else if (typeof e.data === "string") {
|
|
153
|
+
// Preserve original handling for string messages
|
|
138
154
|
if (e.data === "minimize") {
|
|
139
155
|
this.animateMinimize();
|
|
140
156
|
} else if (e.data === "show" || e.data === "maximize") {
|
|
@@ -146,37 +162,107 @@
|
|
|
146
162
|
animateMinimize() {
|
|
147
163
|
if (this.mode !== 'ContactForm') {
|
|
148
164
|
this.iframe.style.height = this.minimizedHeight;
|
|
149
|
-
this.iframe.style.opacity = '0';
|
|
165
|
+
this.iframe.style.opacity = '0';
|
|
150
166
|
setTimeout(() => {
|
|
151
167
|
this.iframe.style.display = "none";
|
|
152
|
-
this.iframe.style.opacity = '1';
|
|
168
|
+
this.iframe.style.opacity = '1';
|
|
153
169
|
this.minimizedIframe.style.display = "block";
|
|
154
170
|
this.minimizedIframe.style.height = this.minimizedHeight;
|
|
155
|
-
this.minimizedIframe.style.opacity = '1';
|
|
156
|
-
}, this.enableAnimation ? 300 : 0);
|
|
171
|
+
this.minimizedIframe.style.opacity = '1';
|
|
172
|
+
}, this.enableAnimation ? 300 : 0);
|
|
157
173
|
}
|
|
158
174
|
}
|
|
159
175
|
|
|
160
|
-
|
|
161
|
-
this.
|
|
176
|
+
animateMaximize() {
|
|
177
|
+
if (this.mode !== 'ContactForm') {
|
|
178
|
+
// Start the animation for minimizing iframe
|
|
179
|
+
this.minimizedIframe.style.height = `${this.height}px`;
|
|
180
|
+
this.minimizedIframe.style.opacity = '0';
|
|
181
|
+
|
|
182
|
+
setTimeout(() => {
|
|
183
|
+
// Hide the minimized iframe
|
|
184
|
+
this.minimizedIframe.style.display = "none";
|
|
185
|
+
this.minimizedIframe.style.opacity = '1'; // Reset opacity
|
|
186
|
+
|
|
187
|
+
// Show and animate the main iframe
|
|
188
|
+
this.iframe.style.display = "block";
|
|
189
|
+
this.iframe.style.height = this.minimizedHeight; // Start with minimized height
|
|
190
|
+
this.iframe.style.opacity = '0'; // Start with zero opacity
|
|
191
|
+
|
|
192
|
+
// Trigger the maximize animation
|
|
193
|
+
setTimeout(() => {
|
|
194
|
+
this.iframe.style.height = `${this.height}px`; // Animate to full height
|
|
195
|
+
this.iframe.style.opacity = '1'; // Animate opacity to full
|
|
196
|
+
}, 10); // Small delay to allow display changes to take effect
|
|
197
|
+
}, this.enableAnimation ? 300 : 0); // Match the minimize animation duration
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
applyIframeUpdates({ locale, width, scale } = {}) {
|
|
202
|
+
// Update locale if provided and different (but do not update the iframe URL)
|
|
203
|
+
if (locale && typeof locale === 'string' && locale !== this.locale) {
|
|
204
|
+
this.locale = locale;
|
|
205
|
+
console.log(`Locale stored locally: ${this.locale}`);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Update width if provided and different
|
|
209
|
+
const parsedWidth = parseInt(width, 10);
|
|
210
|
+
if (!isNaN(parsedWidth) && parsedWidth > 0 && parsedWidth !== this.width) {
|
|
211
|
+
this.width = Math.max(parsedWidth, 320);
|
|
212
|
+
console.log(`Width updated to: ${this.width}px`);
|
|
213
|
+
|
|
214
|
+
// Apply width to container
|
|
215
|
+
this.containerDiv.style.width = `${this.width}px`;
|
|
162
216
|
|
|
163
|
-
|
|
164
|
-
|
|
217
|
+
// Apply width to the main iframe
|
|
218
|
+
if (this.iframe) {
|
|
219
|
+
this.iframe.style.width = `${this.width}px`;
|
|
220
|
+
}
|
|
165
221
|
|
|
166
|
-
|
|
222
|
+
// Apply width to the minimized iframe
|
|
223
|
+
if (this.minimizedIframe) {
|
|
224
|
+
this.minimizedIframe.style.width = `${this.width}px`;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
167
227
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
228
|
+
// Apply scale if provided
|
|
229
|
+
if (typeof scale === 'number' && scale > 0) {
|
|
230
|
+
if (this.iframe) {
|
|
231
|
+
this.iframe.style.transform = `scale(${scale})`;
|
|
232
|
+
this.iframe.style.transformOrigin = "bottom right";
|
|
233
|
+
}
|
|
234
|
+
if (this.minimizedIframe) {
|
|
235
|
+
this.minimizedIframe.style.transform = `scale(${scale})`;
|
|
236
|
+
this.minimizedIframe.style.transformOrigin = "bottom right";
|
|
237
|
+
}
|
|
238
|
+
console.log(`Scale applied: ${scale}`);
|
|
174
239
|
}
|
|
240
|
+
}
|
|
175
241
|
|
|
176
|
-
this.iframe.style.height = `${this.height}px`;
|
|
177
|
-
this.iframe.style.opacity = '1';
|
|
178
242
|
|
|
179
|
-
|
|
243
|
+
showMaximized(animate = false) {
|
|
244
|
+
if (animate) {
|
|
245
|
+
this.animateMaximize();
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
this.minimizedIframe.style.display = "none";
|
|
249
|
+
this.minimizedIframe.style.height = `${this.height}px`;
|
|
250
|
+
this.minimizedIframe.style.opacity = ''; // Reset opacity to unset
|
|
251
|
+
|
|
252
|
+
this.iframe.style.display = "block";
|
|
253
|
+
|
|
254
|
+
if (this.isSafari() && !this.hasRefreshed) {
|
|
255
|
+
const currentSrc = this.iframe.src;
|
|
256
|
+
this.iframe.src = ''; // Temporarily clear the src
|
|
257
|
+
this.iframe.src = currentSrc; // Reset to the original src to trigger a reload
|
|
258
|
+
this.hasRefreshed = true; // Prevent endless loop
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
this.iframe.style.height = `${this.height}px`;
|
|
262
|
+
this.iframe.style.opacity = '1';
|
|
263
|
+
|
|
264
|
+
this.iframe.contentWindow.postMessage({ message: "show" }, "*");
|
|
265
|
+
}
|
|
180
266
|
}
|
|
181
267
|
|
|
182
268
|
applyScale(scale) {
|
|
@@ -245,6 +331,27 @@
|
|
|
245
331
|
|
|
246
332
|
return `${baseIframeUrl}?${urlParams.toString()}`;
|
|
247
333
|
}
|
|
334
|
+
|
|
335
|
+
waitForIframeLoad(iframe, timeout = 5000) {
|
|
336
|
+
return new Promise((resolve, reject) => {
|
|
337
|
+
// Check if the iframe is already loaded
|
|
338
|
+
if (iframe.contentDocument || iframe.contentWindow) {
|
|
339
|
+
resolve();
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Set up a timeout to avoid waiting indefinitely
|
|
344
|
+
const timeoutId = setTimeout(() => {
|
|
345
|
+
reject(new Error('Iframe did not load within the timeout period.'));
|
|
346
|
+
}, timeout);
|
|
347
|
+
|
|
348
|
+
// Add the load event listener
|
|
349
|
+
iframe.addEventListener('load', () => {
|
|
350
|
+
clearTimeout(timeoutId); // Clear the timeout
|
|
351
|
+
resolve();
|
|
352
|
+
}, { once: true }); // Ensure the listener is triggered only once
|
|
353
|
+
});
|
|
354
|
+
}
|
|
248
355
|
}
|
|
249
356
|
|
|
250
357
|
export function initEmbeddedChat(containerDiv, chatId, options) {
|
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "embeddedaichatux",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.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": {
|
|
7
7
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
8
|
},
|
|
9
9
|
"author": "EmbedGPT.chat, LLC",
|
|
10
|
-
"license": "MIT"
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"files": [
|
|
12
|
+
"EmbeddedChat.js"
|
|
13
|
+
]
|
|
11
14
|
}
|
package/AIChat.npm.csproj
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
2
|
-
|
|
3
|
-
<PropertyGroup>
|
|
4
|
-
<TargetFramework>net7.0</TargetFramework>
|
|
5
|
-
<Nullable>enable</Nullable>
|
|
6
|
-
<ImplicitUsings>enable</ImplicitUsings>
|
|
7
|
-
</PropertyGroup>
|
|
8
|
-
|
|
9
|
-
<Target Name="CopyCommonWebFiles" BeforeTargets="Build">
|
|
10
|
-
<ItemGroup>
|
|
11
|
-
<_CommonWebJsFiles Include="..\AIChat.Web\wwwroot\js\EmbeddedChat.js" />
|
|
12
|
-
</ItemGroup>
|
|
13
|
-
|
|
14
|
-
<Copy SourceFiles="@(_CommonWebJsFiles)" DestinationFolder="$(MSBuildProjectDirectory)" SkipUnchangedFiles="true" />
|
|
15
|
-
</Target>
|
|
16
|
-
|
|
17
|
-
<ItemGroup>
|
|
18
|
-
<None Remove="EmbeddedChat.js" />
|
|
19
|
-
</ItemGroup>
|
|
20
|
-
|
|
21
|
-
<ItemGroup>
|
|
22
|
-
<Content Include="EmbeddedChat.js">
|
|
23
|
-
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
|
24
|
-
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
|
25
|
-
</Content>
|
|
26
|
-
</ItemGroup>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
</Project>
|
package/AIChat.npm.csproj.user
DELETED
package/AIChat.npm.sln
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
3
|
-
# Visual Studio Version 17
|
|
4
|
-
VisualStudioVersion = 17.7.34024.191
|
|
5
|
-
MinimumVisualStudioVersion = 10.0.40219.1
|
|
6
|
-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AIChat.npm", "AIChat.npm.csproj", "{37DB7D9F-39C4-428D-A205-7E78FAB8BB25}"
|
|
7
|
-
EndProject
|
|
8
|
-
Global
|
|
9
|
-
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
10
|
-
Debug|Any CPU = Debug|Any CPU
|
|
11
|
-
Release|Any CPU = Release|Any CPU
|
|
12
|
-
EndGlobalSection
|
|
13
|
-
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
14
|
-
{37DB7D9F-39C4-428D-A205-7E78FAB8BB25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
15
|
-
{37DB7D9F-39C4-428D-A205-7E78FAB8BB25}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
16
|
-
{37DB7D9F-39C4-428D-A205-7E78FAB8BB25}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
17
|
-
{37DB7D9F-39C4-428D-A205-7E78FAB8BB25}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
18
|
-
EndGlobalSection
|
|
19
|
-
GlobalSection(SolutionProperties) = preSolution
|
|
20
|
-
HideSolutionNode = FALSE
|
|
21
|
-
EndGlobalSection
|
|
22
|
-
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
23
|
-
SolutionGuid = {33D9F6CE-532F-4C22-AAAD-2D8B3BB56596}
|
|
24
|
-
EndGlobalSection
|
|
25
|
-
EndGlobal
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"iisSettings": {
|
|
3
|
-
"windowsAuthentication": false,
|
|
4
|
-
"anonymousAuthentication": true,
|
|
5
|
-
"iisExpress": {
|
|
6
|
-
"applicationUrl": "http://localhost:27434",
|
|
7
|
-
"sslPort": 44389
|
|
8
|
-
}
|
|
9
|
-
},
|
|
10
|
-
"profiles": {
|
|
11
|
-
"http": {
|
|
12
|
-
"commandName": "Project",
|
|
13
|
-
"dotnetRunMessages": true,
|
|
14
|
-
"launchBrowser": true,
|
|
15
|
-
"applicationUrl": "http://localhost:5103",
|
|
16
|
-
"environmentVariables": {
|
|
17
|
-
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
"https": {
|
|
21
|
-
"commandName": "Project",
|
|
22
|
-
"dotnetRunMessages": true,
|
|
23
|
-
"launchBrowser": true,
|
|
24
|
-
"applicationUrl": "https://localhost:7299;http://localhost:5103",
|
|
25
|
-
"environmentVariables": {
|
|
26
|
-
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
"IIS Express": {
|
|
30
|
-
"commandName": "IISExpress",
|
|
31
|
-
"launchBrowser": true,
|
|
32
|
-
"environmentVariables": {
|
|
33
|
-
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|