aptolix_chatbot 1.0.4 → 1.0.6

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.
@@ -370,6 +370,9 @@
370
370
  min-height: 180px;
371
371
  width: 100vw;
372
372
  max-width: 100vw;
373
+ left: 0;
374
+ right: 0;
375
+ margin: 0;
373
376
  }
374
377
  #aptolix-chat-header {
375
378
  font-size: 1rem;
@@ -381,6 +384,12 @@
381
384
  #aptolix-chat-input {
382
385
  padding: 6px 2px;
383
386
  }
387
+ #aptolix-chat-expand {
388
+ display: none !important;
389
+ }
390
+ #aptolix-chat-window.section-mode #aptolix-chat-close {
391
+ display: none !important;
392
+ }
384
393
  }
385
394
 
386
395
  .aptolix-retry-btn {
@@ -397,5 +406,34 @@
397
406
  background: #d8b4fe;
398
407
  }
399
408
 
409
+ .aptolix-hint-bubble {
410
+ position: fixed;
411
+ bottom: 110px; /* Adjust so it's above the bubble */
412
+ right: 40px; /* Adjust to align with bubble */
413
+ background: #fff;
414
+ color: #333;
415
+ padding: 10px 18px;
416
+ border-radius: 18px;
417
+ box-shadow: 0 2px 12px rgba(0,0,0,0.12);
418
+ font-size: 15px;
419
+ z-index: 9999;
420
+ transition: opacity 0.3s;
421
+ opacity: 1;
422
+ pointer-events: none;
423
+ max-width: 220px;
424
+ }
425
+
426
+ .aptolix-hint-bubble::after {
427
+ content: "";
428
+ position: absolute;
429
+ bottom: -12px; /* Position arrow below the bubble */
430
+ right: 28px; /* Align arrow with bubble */
431
+ width: 0;
432
+ height: 0;
433
+ border-left: 10px solid transparent;
434
+ border-right: 10px solid transparent;
435
+ border-top: 12px solid #fff; /* Same as bubble background */
436
+ }
437
+
400
438
 
401
439
 
package/src/index.js CHANGED
@@ -2,19 +2,48 @@
2
2
  import './chatbotstyle.css';
3
3
 
4
4
  const AptolixChatbot = {
5
- init: ({ apiHost, chatflowid, title, subtitle, greeting, mode = "bubble", target }) => {
5
+ init: ({ apiHost, chatflowid, title, subtitle, greeting, mode = "bubble", target, hintText = "I am here to help", hintDelay = 5000 // default 5 seconds
6
+ }) => {
6
7
 
7
8
  const modeClass = mode === "section" ? "section-mode" : "bubble-mode";
9
+ const chatWindow = document.createElement('div');
8
10
 
9
- let bubble;
11
+ let bubble, hintBubbleTimeout, hintBubble;
10
12
  if (mode === "bubble") {
11
13
  bubble = document.createElement('div');
12
14
  bubble.id = "aptolix-chat-bubble";
13
15
  bubble.innerText = "💬";
14
16
  document.body.appendChild(bubble);
17
+
18
+ // Create hint bubble but keep it hidden initially
19
+ hintBubble = document.createElement('div');
20
+ hintBubble.id = "aptolix-chat-hint-bubble";
21
+ hintBubble.className = "aptolix-hint-bubble";
22
+ hintBubble.innerText = hintText;
23
+ hintBubble.style.display = "none";
24
+ document.body.appendChild(hintBubble);
25
+
26
+ // Show hint bubble after delay
27
+ hintBubbleTimeout = setTimeout(() => {
28
+ if (chatWindow.style.display === "none") {
29
+ hintBubble.style.display = "block";
30
+ }
31
+ }, hintDelay);
32
+
33
+ // Hide hint bubble when main bubble is clicked
34
+ bubble.addEventListener("click", () => {
35
+ hintBubble.style.display = "none";
36
+ clearTimeout(hintBubbleTimeout);
37
+ });
38
+
39
+ // Hide hint bubble if chat is opened by other means
40
+ chatWindow.addEventListener("transitionstart", () => {
41
+ hintBubble.style.display = "none";
42
+ clearTimeout(hintBubbleTimeout);
43
+ });
15
44
  }
16
45
 
17
- const chatWindow = document.createElement('div');
46
+
18
47
  chatWindow.id = "aptolix-chat-window";
19
48
  chatWindow.classList.add(modeClass);
20
49
  chatWindow.style.display = mode === "section" ? "flex" : "none";
@@ -31,7 +60,7 @@ const AptolixChatbot = {
31
60
  <div id="aptolix-chat-header">
32
61
  <div class="aptolix-header-flex">
33
62
  <div class="aptolix-header-title">
34
- <strong>${title || "Assistant"}</strong>
63
+ <strong>${title || "AI Chatbot"}</strong>
35
64
  ${subtitle ? `<div class="aptolix-header-subtitle">${subtitle}</div>` : ""}
36
65
  </div>
37
66
  <div class="aptolix-header-actions">
@@ -39,6 +68,7 @@ const AptolixChatbot = {
39
68
  <button id="aptolix-chat-expand" title="Expand/Collapse" aria-label="Expand/Collapse">
40
69
  <span id="aptolix-chat-expand-icon">⤢</span>
41
70
  </button>
71
+ <button id="aptolix-chat-download" title="Download chat" aria-label="Download chat">⤓</button>
42
72
  <button id="aptolix-chat-close" title="Close chat" aria-label="Close chat">×</button>
43
73
  </div>
44
74
  </div>
@@ -60,6 +90,7 @@ const AptolixChatbot = {
60
90
  const input = chatWindow.querySelector("#aptolix-chat-inputbox");
61
91
  const sendButton = chatWindow.querySelector("button");
62
92
  const messagesDiv = chatWindow.querySelector("#aptolix-chat-messages");
93
+ const downloadBtn = chatWindow.querySelector("#aptolix-chat-download");
63
94
 
64
95
  if (mode === "bubble") {
65
96
  closeBtn.addEventListener("click", () => {
@@ -98,8 +129,12 @@ const AptolixChatbot = {
98
129
  async function sendMessage(isRetry = false, previousText = null) {
99
130
  const userText = previousText || input.value.trim();
100
131
  if (!userText) return;
101
- if (!isRetry) input.value = "";
102
-
132
+ if (!isRetry) {
133
+ input.value = "";
134
+ input.rows = 1;
135
+ input.style.height = "32px"; // or your default line height
136
+ input.style.overflowY = "hidden";
137
+ }
103
138
  if (!isRetry) {
104
139
  const userMsg = document.createElement("div");
105
140
  userMsg.className = "message user";
@@ -202,10 +237,22 @@ const AptolixChatbot = {
202
237
  setTimeout(showGreeting, 100);
203
238
 
204
239
  input.addEventListener('input', function() {
240
+ // Restrict to max 350 characters
241
+ if (this.value.length > 350) {
242
+ this.value = this.value.slice(0, 350);
243
+ return;
244
+ }
245
+ // If textarea is empty, reset to default size
246
+ if (this.value === "") {
247
+ this.rows = 1;
248
+ this.style.height = "32px";
249
+ this.style.overflowY = "hidden";
250
+ return;
251
+ }
205
252
  // Count the number of lines in the textarea
206
- const lines = this.value.split('\n').length;
253
+ const lines = this.value.split('\n');
207
254
  // Set the number of rows, max 4
208
- this.rows = Math.min(lines, 4);
255
+ this.rows = Math.min(lines.length, 4);
209
256
  // Calculate the max height for 4 rows (approximate line height: 32px)
210
257
  const maxHeight = 3 * 36; // 128px
211
258
  this.style.height = 'auto';
@@ -217,6 +264,29 @@ const AptolixChatbot = {
217
264
  this.style.overflowY = 'hidden';
218
265
  }
219
266
  });
267
+
268
+ downloadBtn.addEventListener("click", () => {
269
+ // Collect all messages
270
+ const messages = Array.from(messagesDiv.querySelectorAll('.message')).map(msg => {
271
+ const sender = msg.classList.contains('user') ? "You" : "Bot";
272
+ // Remove HTML tags for plain text
273
+ const text = msg.innerText || msg.textContent;
274
+ return `${sender}: ${text}`;
275
+ }).join('\n\n');
276
+
277
+ // Create a blob and trigger download
278
+ const blob = new Blob([messages], { type: "text/plain" });
279
+ const url = URL.createObjectURL(blob);
280
+ const a = document.createElement("a");
281
+ a.href = url;
282
+ a.download = "chat_history.txt";
283
+ document.body.appendChild(a);
284
+ a.click();
285
+ setTimeout(() => {
286
+ document.body.removeChild(a);
287
+ URL.revokeObjectURL(url);
288
+ }, 100);
289
+ });
220
290
  },
221
291
  initFull: function(options) {
222
292
  let el = document.querySelector('aptolix-chatbot');
@@ -254,7 +324,7 @@ class AptolixChatbotElement extends HTMLElement {
254
324
  const chatflowid = this.getAttribute('chatflowid');
255
325
  if (!apiHost || !chatflowid) return;
256
326
 
257
- const title = this.getAttribute('title') || "Aptolix Assistant";
327
+ const title = this.getAttribute('title') || "Aptolix AI Chatbot";
258
328
  const greeting = this.getAttribute('greeting');
259
329
  const subtitle = this.getAttribute('subtitle');
260
330
  const targetAttr = this.getAttribute('target');
@@ -286,3 +356,4 @@ export default AptolixChatbot;
286
356
 
287
357
 
288
358
 
359
+