@ihoomanai/chat-widget 3.0.21 → 4.0.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/cdn/SRI_HASHES.md +8 -8
- package/cdn/health.json +2 -2
- package/cdn/latest/chat.js +57 -55
- package/cdn/latest/chat.js.map +1 -1
- package/cdn/latest/chat.min.js +1 -1
- package/cdn/latest/chat.min.js.map +1 -1
- package/cdn/manifest.json +9 -9
- package/cdn/v3/chat.js +58 -56
- package/cdn/v3/chat.js.map +1 -1
- package/cdn/v3/chat.min.js +1 -1
- package/cdn/v3/chat.min.js.map +1 -1
- package/cdn/{v3.0.16 → v3.0.21}/chat.js +57 -55
- package/cdn/v3.0.21/chat.js.map +1 -0
- package/cdn/v3.0.21/chat.min.js +2 -0
- package/cdn/v3.0.21/chat.min.js.map +1 -0
- package/dist/index.cjs.js +231 -167
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +231 -167
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/dist/index.umd.js +231 -167
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +1 -1
- package/dist/index.umd.min.js.map +1 -1
- package/dist/widget.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/widget.ts +236 -169
- package/cdn/v3.0.16/chat.js.map +0 -1
- package/cdn/v3.0.16/chat.min.js +0 -2
- package/cdn/v3.0.16/chat.min.js.map +0 -1
package/src/widget.ts
CHANGED
|
@@ -17,21 +17,21 @@ import type {
|
|
|
17
17
|
WidgetView,
|
|
18
18
|
} from './types';
|
|
19
19
|
|
|
20
|
-
const VERSION = '
|
|
20
|
+
const VERSION = '4.0.0';
|
|
21
21
|
const STORAGE_PREFIX = 'ihooman_chat_';
|
|
22
22
|
const DEFAULT_SERVER_URL = 'https://api.ihooman.ai';
|
|
23
23
|
|
|
24
24
|
const defaultConfig: Partial<WidgetConfig> = {
|
|
25
25
|
serverUrl: DEFAULT_SERVER_URL,
|
|
26
|
-
theme: '
|
|
26
|
+
theme: 'dark',
|
|
27
27
|
position: 'bottom-right',
|
|
28
|
-
title: '
|
|
29
|
-
subtitle: '
|
|
30
|
-
welcomeMessage: '
|
|
31
|
-
placeholder: '
|
|
32
|
-
primaryColor: '#
|
|
33
|
-
gradientFrom: '#
|
|
34
|
-
gradientTo: '#
|
|
28
|
+
title: 'AI Assistant',
|
|
29
|
+
subtitle: 'Always here to help',
|
|
30
|
+
welcomeMessage: 'Hello! How can I help you today?',
|
|
31
|
+
placeholder: 'Send a message...',
|
|
32
|
+
primaryColor: '#ededed',
|
|
33
|
+
gradientFrom: '#171717',
|
|
34
|
+
gradientTo: '#171717',
|
|
35
35
|
showTimestamps: true,
|
|
36
36
|
showTypingIndicator: true,
|
|
37
37
|
enableSounds: true,
|
|
@@ -39,11 +39,11 @@ const defaultConfig: Partial<WidgetConfig> = {
|
|
|
39
39
|
startOpen: false,
|
|
40
40
|
persistSession: true,
|
|
41
41
|
zIndex: 9999,
|
|
42
|
-
width:
|
|
43
|
-
height:
|
|
44
|
-
buttonSize:
|
|
42
|
+
width: 400,
|
|
43
|
+
height: 620,
|
|
44
|
+
buttonSize: 52,
|
|
45
45
|
borderRadius: 16,
|
|
46
|
-
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
46
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto, sans-serif',
|
|
47
47
|
avatarUrl: '',
|
|
48
48
|
poweredBy: true,
|
|
49
49
|
presetQuestions: [],
|
|
@@ -54,22 +54,23 @@ const defaultConfig: Partial<WidgetConfig> = {
|
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
const icons = {
|
|
57
|
-
chat: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="
|
|
58
|
-
close: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="
|
|
59
|
-
send: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="
|
|
60
|
-
attach: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="
|
|
61
|
-
minimize: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
57
|
+
chat: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>`,
|
|
58
|
+
close: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>`,
|
|
59
|
+
send: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="m12 5 7 7-7 7"></path></svg>`,
|
|
60
|
+
attach: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"></path></svg>`,
|
|
61
|
+
minimize: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"></path></svg>`,
|
|
62
|
+
sparkle: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"></path></svg>`,
|
|
63
|
+
bot: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M12 8V4H8"></path><rect width="16" height="12" x="4" y="8" rx="2"></rect><path d="M2 14h2"></path><path d="M20 14h2"></path><path d="M15 13v2"></path><path d="M9 13v2"></path></svg>`,
|
|
64
|
+
agent: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="5"></circle><path d="M20 21a8 8 0 0 0-16 0"></path></svg>`,
|
|
65
|
+
ticket: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"></path><path d="M14 2v4a2 2 0 0 0 2 2h4"></path><path d="M10 18v-1"></path><path d="M14 18v-1"></path><path d="M10 14v-1"></path><path d="M14 14v-1"></path></svg>`,
|
|
66
|
+
history: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"></path><path d="M3 3v5h5"></path><path d="M12 7v5l4 2"></path></svg>`,
|
|
67
|
+
plus: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"></path><path d="M12 5v14"></path></svg>`,
|
|
68
|
+
star: `<svg viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="1"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg>`,
|
|
69
|
+
starEmpty: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon></svg>`,
|
|
70
|
+
thumbUp: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M7 10v12"></path><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"></path></svg>`,
|
|
71
|
+
thumbDown: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M17 14V2"></path><path d="M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z"></path></svg>`,
|
|
72
|
+
chevronLeft: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"></path></svg>`,
|
|
73
|
+
chevronRight: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"></path></svg>`,
|
|
73
74
|
};
|
|
74
75
|
|
|
75
76
|
let config: WidgetConfig = { widgetId: '', ...defaultConfig };
|
|
@@ -245,22 +246,34 @@ function matchUrlPattern(pattern: string): boolean {
|
|
|
245
246
|
// ============================================================================
|
|
246
247
|
|
|
247
248
|
function generateStyles(): string {
|
|
248
|
-
const {
|
|
249
|
-
const isDark = config.theme === 'dark';
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const
|
|
253
|
-
const
|
|
254
|
-
const
|
|
255
|
-
const
|
|
256
|
-
const
|
|
249
|
+
const { fontFamily, borderRadius, zIndex, width, height, buttonSize } = config;
|
|
250
|
+
const isDark = config.theme === 'dark' || config.theme === 'auto';
|
|
251
|
+
|
|
252
|
+
// Professional dark/light color tokens — Vercel-inspired
|
|
253
|
+
const bgColor = isDark ? '#0a0a0a' : '#ffffff';
|
|
254
|
+
const bgElevated = isDark ? '#141414' : '#fafafa';
|
|
255
|
+
const bgSurface = isDark ? '#1a1a1a' : '#f4f4f5';
|
|
256
|
+
const textColor = isDark ? '#ededed' : '#09090b';
|
|
257
|
+
const textSecondary = isDark ? '#a1a1aa' : '#71717a';
|
|
258
|
+
const mutedColor = isDark ? '#52525b' : '#a1a1aa';
|
|
259
|
+
const borderColor = isDark ? '#27272a' : '#e4e4e7';
|
|
260
|
+
const borderSubtle = isDark ? '#1f1f23' : '#f4f4f5';
|
|
261
|
+
const inputBg = isDark ? '#141414' : '#fafafa';
|
|
262
|
+
const hoverBg = isDark ? '#1c1c1c' : '#f4f4f5';
|
|
263
|
+
const accentColor = isDark ? '#ededed' : '#18181b';
|
|
264
|
+
const accentBg = isDark ? '#ededed' : '#18181b';
|
|
265
|
+
const accentText = isDark ? '#09090b' : '#fafafa';
|
|
266
|
+
const userMsgBg = isDark ? '#27272a' : '#18181b';
|
|
267
|
+
const userMsgText = isDark ? '#ededed' : '#fafafa';
|
|
268
|
+
const botMsgBg = 'transparent';
|
|
257
269
|
const positionRight = config.position?.includes('right') ?? true;
|
|
258
270
|
const positionBottom = config.position?.includes('bottom') ?? true;
|
|
271
|
+
const shadowLg = isDark ? '0 24px 48px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.05)' : '0 24px 48px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.05)';
|
|
259
272
|
|
|
260
273
|
return `
|
|
261
274
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
262
275
|
:host { all: initial; }
|
|
263
|
-
.ihooman-widget { font-family: ${fontFamily}; font-size: 14px; line-height: 1.
|
|
276
|
+
.ihooman-widget { font-family: ${fontFamily}; font-size: 14px; line-height: 1.6; color: ${textColor}; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
|
|
264
277
|
button {
|
|
265
278
|
font-family: inherit;
|
|
266
279
|
font-size: 100%;
|
|
@@ -273,144 +286,188 @@ function generateStyles(): string {
|
|
|
273
286
|
cursor: pointer;
|
|
274
287
|
outline: none;
|
|
275
288
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
.ihooman-toggle
|
|
280
|
-
.ihooman-toggle
|
|
281
|
-
.ihooman-toggle
|
|
282
|
-
.ihooman-toggle
|
|
289
|
+
button:focus-visible { outline: 2px solid ${accentColor}; outline-offset: 2px; }
|
|
290
|
+
|
|
291
|
+
/* ── Toggle Button ── */
|
|
292
|
+
.ihooman-toggle { position: fixed !important; ${positionRight ? 'right: 20px' : 'left: 20px'}; ${positionBottom ? 'bottom: 20px' : 'top: 20px'}; width: ${buttonSize}px !important; height: ${buttonSize}px !important; border-radius: 50% !important; background: ${accentBg} !important; border: 1px solid ${borderColor} !important; cursor: pointer; z-index: ${zIndex}; display: flex !important; align-items: center; justify-content: center; box-shadow: ${shadowLg}; transition: all 0.2s ease-out; overflow: hidden; }
|
|
293
|
+
.ihooman-toggle:hover { transform: scale(1.05); box-shadow: ${shadowLg}; }
|
|
294
|
+
.ihooman-toggle:active { transform: scale(0.96); }
|
|
295
|
+
.ihooman-toggle svg { width: 22px; height: 22px; color: ${accentText}; transition: transform 0.25s ease-out, opacity 0.15s ease; position: relative; z-index: 1; }
|
|
296
|
+
.ihooman-toggle .chat-icon { display: flex; align-items: center; justify-content: center; transition: transform 0.25s ease-out, opacity 0.15s ease; }
|
|
297
|
+
.ihooman-toggle .close-icon { position: absolute; display: flex; align-items: center; justify-content: center; transform: rotate(-90deg) scale(0); opacity: 0; transition: transform 0.25s ease-out, opacity 0.15s ease; }
|
|
283
298
|
.ihooman-toggle.open .chat-icon { transform: rotate(90deg) scale(0); opacity: 0; }
|
|
284
299
|
.ihooman-toggle.open .close-icon { transform: rotate(0) scale(1); opacity: 1; }
|
|
285
|
-
.ihooman-pulse {
|
|
286
|
-
|
|
287
|
-
.ihooman-toggle.open .ihooman-pulse { display: none; }
|
|
288
|
-
.ihooman-badge { position: absolute; top: -4px; right: -4px; min-width: 20px; height: 20px; padding: 0 6px; background: #ef4444; color: white; font-size: 11px; font-weight: 600; border-radius: 10px; display: flex; align-items: center; justify-content: center; z-index: 2; }
|
|
300
|
+
.ihooman-pulse { display: none; }
|
|
301
|
+
.ihooman-badge { position: absolute; top: -3px; right: -3px; min-width: 18px; height: 18px; padding: 0 5px; background: #dc2626; color: white; font-size: 10px; font-weight: 600; border-radius: 9px; display: flex; align-items: center; justify-content: center; z-index: 2; border: 2px solid ${bgColor}; }
|
|
289
302
|
.ihooman-badge:empty { display: none; }
|
|
290
|
-
|
|
303
|
+
|
|
304
|
+
/* ── Window ── */
|
|
305
|
+
.ihooman-window { position: fixed; ${positionRight ? 'right: 20px' : 'left: 20px'}; ${positionBottom ? 'bottom: 84px' : 'top: 84px'}; width: ${width}px; height: ${height}px; min-height: ${height}px; max-height: ${height}px; z-index: ${(zIndex ?? 9999) - 1}; display: flex; flex-direction: column; opacity: 0; visibility: hidden; transform: translateY(12px) scale(0.97); transition: opacity 0.2s ease-out, visibility 0.2s ease-out, transform 0.2s ease-out; overscroll-behavior: contain; }
|
|
291
306
|
.ihooman-window.open { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
.ihooman-container
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
.ihooman-header
|
|
298
|
-
.ihooman-header-avatar
|
|
307
|
+
|
|
308
|
+
/* ── Container ── */
|
|
309
|
+
.ihooman-container { position: relative; width: 100%; height: 100%; display: flex; flex-direction: column; border-radius: ${borderRadius}px; overflow: hidden; flex-shrink: 0; background: ${bgColor}; border: 1px solid ${borderColor}; box-shadow: ${shadowLg}; }
|
|
310
|
+
|
|
311
|
+
/* ── Header ── */
|
|
312
|
+
.ihooman-header { padding: 14px 16px; background: ${bgElevated}; color: ${textColor}; display: flex; align-items: center; gap: 12px; flex-shrink: 0; border-bottom: 1px solid ${borderColor}; }
|
|
313
|
+
.ihooman-header-avatar { width: 36px; height: 36px; border-radius: 10px; background: ${bgSurface}; display: flex; align-items: center; justify-content: center; flex-shrink: 0; border: 1px solid ${borderColor}; }
|
|
314
|
+
.ihooman-header-avatar img { width: 100%; height: 100%; border-radius: 10px; object-fit: cover; }
|
|
315
|
+
.ihooman-header-avatar svg { width: 18px; height: 18px; color: ${textSecondary}; }
|
|
299
316
|
.ihooman-header-info { flex: 1; min-width: 0; }
|
|
300
|
-
.ihooman-header-title { font-size:
|
|
301
|
-
.ihooman-header-status { display: flex; align-items: center; gap:
|
|
302
|
-
.ihooman-status-dot { width:
|
|
303
|
-
.ihooman-status-dot.offline { background: #
|
|
304
|
-
.ihooman-header-actions { display: flex; gap:
|
|
305
|
-
.ihooman-header-btn { width:
|
|
306
|
-
.ihooman-header-btn:hover { background:
|
|
307
|
-
.ihooman-header-btn svg { width:
|
|
308
|
-
|
|
309
|
-
|
|
317
|
+
.ihooman-header-title { font-size: 14px; font-weight: 600; margin-bottom: 1px; letter-spacing: -0.01em; color: ${textColor}; }
|
|
318
|
+
.ihooman-header-status { display: flex; align-items: center; gap: 5px; font-size: 12px; color: ${textSecondary}; }
|
|
319
|
+
.ihooman-status-dot { width: 6px; height: 6px; border-radius: 50%; background: #22c55e; flex-shrink: 0; }
|
|
320
|
+
.ihooman-status-dot.offline { background: #a1a1aa; }
|
|
321
|
+
.ihooman-header-actions { display: flex; gap: 4px; }
|
|
322
|
+
.ihooman-header-btn { width: 30px; height: 30px; border-radius: 8px; background: transparent; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; color: ${textSecondary}; transition: background 0.15s ease, color 0.15s ease; }
|
|
323
|
+
.ihooman-header-btn:hover { background: ${hoverBg}; color: ${textColor}; }
|
|
324
|
+
.ihooman-header-btn svg { width: 15px; height: 15px; }
|
|
325
|
+
|
|
326
|
+
/* ── Messages ── */
|
|
327
|
+
.ihooman-messages { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 20px 16px; display: flex; flex-direction: column; gap: 6px; background: ${bgColor}; overscroll-behavior: contain; min-height: 0; }
|
|
328
|
+
.ihooman-messages::-webkit-scrollbar { width: 4px; }
|
|
310
329
|
.ihooman-messages::-webkit-scrollbar-track { background: transparent; }
|
|
311
|
-
.ihooman-messages::-webkit-scrollbar-thumb { background: ${
|
|
312
|
-
.ihooman-message { display: flex; flex-direction: column; max-width:
|
|
313
|
-
@keyframes ihooman-fadeIn { from { opacity: 0; transform: translateY(
|
|
330
|
+
.ihooman-messages::-webkit-scrollbar-thumb { background: ${isDark ? '#27272a' : '#d4d4d8'}; border-radius: 2px; }
|
|
331
|
+
.ihooman-message { display: flex; flex-direction: column; max-width: 88%; animation: ihooman-fadeIn 0.25s ease-out; }
|
|
332
|
+
@keyframes ihooman-fadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
|
|
314
333
|
.ihooman-message.user { align-self: flex-end; align-items: flex-end; }
|
|
315
|
-
.ihooman-message.bot { align-self: flex-start; align-items: flex-start; }
|
|
316
|
-
.ihooman-message-content { padding:
|
|
317
|
-
.ihooman-message.user .ihooman-message-content { background: ${
|
|
318
|
-
.ihooman-message.bot .ihooman-message-content { background: ${
|
|
319
|
-
.ihooman-message-content
|
|
320
|
-
.ihooman-message-
|
|
321
|
-
.ihooman-
|
|
322
|
-
.ihooman-
|
|
323
|
-
.ihooman-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
334
|
+
.ihooman-message.bot { align-self: flex-start; align-items: flex-start; max-width: 100%; }
|
|
335
|
+
.ihooman-message-content { padding: 10px 14px; border-radius: 14px; word-wrap: break-word; overflow-wrap: break-word; font-size: 14px; line-height: 1.6; }
|
|
336
|
+
.ihooman-message.user .ihooman-message-content { background: ${userMsgBg}; color: ${userMsgText}; border-bottom-right-radius: 4px; }
|
|
337
|
+
.ihooman-message.bot .ihooman-message-content { background: ${botMsgBg}; color: ${textColor}; padding: 6px 2px; }
|
|
338
|
+
.ihooman-message-content a { color: ${isDark ? '#60a5fa' : '#2563eb'}; text-decoration: underline; text-underline-offset: 2px; }
|
|
339
|
+
.ihooman-message-content a:hover { opacity: 0.8; }
|
|
340
|
+
.ihooman-message-content code { background: ${isDark ? '#27272a' : '#f4f4f5'}; padding: 2px 6px; border-radius: 4px; font-family: 'SF Mono', 'Fira Code', 'Fira Mono', Menlo, Consolas, monospace; font-size: 12.5px; border: 1px solid ${borderSubtle}; }
|
|
341
|
+
.ihooman-message-content strong { font-weight: 600; }
|
|
342
|
+
.ihooman-message-time { font-size: 11px; color: ${mutedColor}; margin-top: 3px; padding: 0 4px; }
|
|
343
|
+
|
|
344
|
+
/* ── Typing Indicator — Shimmer ── */
|
|
345
|
+
.ihooman-typing { display: flex; align-items: center; gap: 10px; padding: 10px 2px; max-width: 180px; align-self: flex-start; animation: ihooman-fadeIn 0.2s ease-out; }
|
|
346
|
+
.ihooman-typing-shimmer { font-size: 13px; color: ${mutedColor}; background: linear-gradient(90deg, ${mutedColor} 25%, ${textSecondary} 50%, ${mutedColor} 75%); background-size: 200% 100%; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; animation: ihooman-shimmer 1.5s ease-in-out infinite; }
|
|
347
|
+
@keyframes ihooman-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
|
|
348
|
+
.ihooman-typing-dots { display: flex; gap: 3px; align-items: center; }
|
|
349
|
+
.ihooman-typing-dot { width: 5px; height: 5px; background: ${mutedColor}; border-radius: 50%; animation: ihooman-typing 1.2s ease-in-out infinite; }
|
|
350
|
+
.ihooman-typing-dot:nth-child(2) { animation-delay: 0.15s; }
|
|
351
|
+
.ihooman-typing-dot:nth-child(3) { animation-delay: 0.3s; }
|
|
352
|
+
@keyframes ihooman-typing { 0%, 60%, 100% { opacity: 0.3; transform: scale(0.8); } 30% { opacity: 1; transform: scale(1); } }
|
|
353
|
+
|
|
354
|
+
/* ── Input Area ── */
|
|
327
355
|
.ihooman-input-area { padding: 12px 16px; background: ${bgColor}; border-top: 1px solid ${borderColor}; flex-shrink: 0; }
|
|
328
|
-
.ihooman-input-wrapper { display: flex; align-items: flex-end; gap: 8px; background: ${inputBg}; border: 1px solid ${borderColor}; border-radius: 12px; padding: 8px 12px; transition: border-color 0.
|
|
329
|
-
.ihooman-input-wrapper:focus-within { border-color: ${
|
|
330
|
-
.ihooman-input { flex: 1; border: none; background: transparent; font-family: inherit; font-size: 14px; color: ${textColor}; resize: none; max-height: 100px; outline: none; line-height: 1.
|
|
356
|
+
.ihooman-input-wrapper { display: flex; align-items: flex-end; gap: 8px; background: ${inputBg}; border: 1px solid ${borderColor}; border-radius: 12px; padding: 8px 12px; transition: border-color 0.15s ease, box-shadow 0.15s ease; }
|
|
357
|
+
.ihooman-input-wrapper:focus-within { border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
|
|
358
|
+
.ihooman-input { flex: 1; border: none; background: transparent; font-family: inherit; font-size: 14px; color: ${textColor}; resize: none; max-height: 100px; outline: none; line-height: 1.5; }
|
|
331
359
|
.ihooman-input::placeholder { color: ${mutedColor}; }
|
|
332
|
-
.ihooman-input-btn { width:
|
|
333
|
-
.ihooman-input-btn:hover {
|
|
334
|
-
.ihooman-input-btn.send { background:
|
|
335
|
-
.ihooman-input-btn.send:hover { opacity: 0.
|
|
336
|
-
.ihooman-input-btn.send:disabled { opacity: 0.
|
|
360
|
+
.ihooman-input-btn { width: 30px; height: 30px; border-radius: 8px; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.15s ease; background: transparent; color: ${mutedColor}; flex-shrink: 0; }
|
|
361
|
+
.ihooman-input-btn:hover { color: ${textColor}; background: ${hoverBg}; }
|
|
362
|
+
.ihooman-input-btn.send { background: ${accentBg}; color: ${accentText}; }
|
|
363
|
+
.ihooman-input-btn.send:hover { opacity: 0.85; }
|
|
364
|
+
.ihooman-input-btn.send:disabled { opacity: 0.3; cursor: not-allowed; }
|
|
337
365
|
.ihooman-input-btn svg { width: 16px; height: 16px; }
|
|
338
|
-
.ihooman-input:disabled { opacity: 0.
|
|
339
|
-
.ihooman-input-btn.attach:disabled { opacity: 0.
|
|
366
|
+
.ihooman-input:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
367
|
+
.ihooman-input-btn.attach:disabled { opacity: 0.3; cursor: not-allowed; }
|
|
340
368
|
.ihooman-file-input { display: none; }
|
|
341
|
-
|
|
342
|
-
|
|
369
|
+
|
|
370
|
+
/* ── Powered By ── */
|
|
371
|
+
.ihooman-powered { text-align: center; padding: 8px; font-size: 11px; color: ${mutedColor}; background: ${bgColor}; border-top: 1px solid ${borderSubtle}; }
|
|
372
|
+
.ihooman-powered a { color: ${textSecondary}; text-decoration: none; font-weight: 500; }
|
|
373
|
+
.ihooman-powered a:hover { color: ${textColor}; }
|
|
374
|
+
|
|
375
|
+
/* ── Escalation ── */
|
|
343
376
|
.ihooman-escalation-actions { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
|
|
344
377
|
.ihooman-escalation-btn svg { width: 14px; height: 14px; flex-shrink: 0; }
|
|
345
|
-
|
|
378
|
+
|
|
379
|
+
/* ── Status Bar ── */
|
|
380
|
+
.ihooman-status-bar { padding: 8px 16px; text-align: center; font-size: 12px; display: none; font-weight: 500; }
|
|
346
381
|
.ihooman-status-bar.show { display: block; }
|
|
347
|
-
.ihooman-status-bar.waiting { background: #
|
|
348
|
-
.ihooman-status-bar.connected { background: #dcfce7; color: #166534; }
|
|
382
|
+
.ihooman-status-bar.waiting { background: ${isDark ? '#1c1917' : '#fef9c3'}; color: ${isDark ? '#fbbf24' : '#92400e'}; border-bottom: 1px solid ${isDark ? '#292524' : '#fef08a'}; }
|
|
383
|
+
.ihooman-status-bar.connected { background: ${isDark ? '#052e16' : '#dcfce7'}; color: ${isDark ? '#4ade80' : '#166534'}; border-bottom: 1px solid ${isDark ? '#14532d' : '#bbf7d0'}; }
|
|
384
|
+
|
|
385
|
+
/* ── Chat View ── */
|
|
349
386
|
.ihooman-chat-view { display: flex; flex-direction: column; flex: 1; overflow: hidden; min-height: 0; }
|
|
350
387
|
.ihooman-chat-view.hidden { display: none; }
|
|
351
|
-
|
|
388
|
+
|
|
389
|
+
/* ── Ticket View ── */
|
|
390
|
+
.ihooman-ticket-view { display: none; flex-direction: column; padding: 20px; gap: 14px; background: ${bgColor}; flex: 1; overflow-y: auto; min-height: 0; }
|
|
352
391
|
.ihooman-ticket-view.show { display: flex; }
|
|
353
|
-
.ihooman-ticket-title { font-size:
|
|
354
|
-
.ihooman-ticket-subtitle { font-size: 13px; color: ${
|
|
355
|
-
.ihooman-ticket-input { padding:
|
|
356
|
-
.ihooman-ticket-input:focus { border-color: ${
|
|
392
|
+
.ihooman-ticket-title { font-size: 16px; font-weight: 600; color: ${textColor}; margin: 0; letter-spacing: -0.01em; }
|
|
393
|
+
.ihooman-ticket-subtitle { font-size: 13px; color: ${textSecondary}; margin: 0; }
|
|
394
|
+
.ihooman-ticket-input { padding: 10px 14px; border: 1px solid ${borderColor}; border-radius: 10px; font-size: 14px; font-family: inherit; background: ${inputBg}; color: ${textColor}; outline: none; transition: border-color 0.15s ease; }
|
|
395
|
+
.ihooman-ticket-input:focus { border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
|
|
357
396
|
.ihooman-ticket-input::placeholder { color: ${mutedColor}; }
|
|
358
397
|
.ihooman-ticket-textarea { min-height: 100px; resize: vertical; }
|
|
359
|
-
.ihooman-ticket-submit { display: flex; align-items: center; justify-content: center; padding:
|
|
360
|
-
.ihooman-ticket-submit:hover { opacity: 0.
|
|
361
|
-
.ihooman-ticket-submit:disabled { opacity: 0.
|
|
362
|
-
.ihooman-ticket-back { display: flex; align-items: center; justify-content: center; padding: 10px; background: transparent; color: ${
|
|
363
|
-
.ihooman-ticket-back:hover { background: ${
|
|
398
|
+
.ihooman-ticket-submit { display: flex; align-items: center; justify-content: center; padding: 10px; background: ${accentBg}; color: ${accentText}; border: none; border-radius: 10px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.15s ease; line-height: 1.4; }
|
|
399
|
+
.ihooman-ticket-submit:hover { opacity: 0.85; }
|
|
400
|
+
.ihooman-ticket-submit:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
401
|
+
.ihooman-ticket-back { display: flex; align-items: center; justify-content: center; padding: 10px; background: transparent; color: ${textSecondary}; border: 1px solid ${borderColor}; border-radius: 10px; font-size: 13px; cursor: pointer; transition: all 0.15s ease; line-height: 1.4; }
|
|
402
|
+
.ihooman-ticket-back:hover { background: ${hoverBg}; color: ${textColor}; }
|
|
403
|
+
|
|
404
|
+
/* ── History View ── */
|
|
364
405
|
.ihooman-history-view { display: none; flex-direction: column; flex: 1; overflow: hidden; background: ${bgColor}; }
|
|
365
406
|
.ihooman-history-view.show { display: flex; }
|
|
366
407
|
.ihooman-history-header { padding: 12px 16px; border-bottom: 1px solid ${borderColor}; display: flex; justify-content: space-between; align-items: center; }
|
|
367
|
-
.ihooman-history-title { font-size:
|
|
368
|
-
.ihooman-history-new { display: inline-flex; align-items: center; justify-content: center; gap: 4px; background:
|
|
369
|
-
.ihooman-history-new:hover { opacity: 0.
|
|
408
|
+
.ihooman-history-title { font-size: 13px; font-weight: 600; color: ${textColor}; margin: 0; }
|
|
409
|
+
.ihooman-history-new { display: inline-flex; align-items: center; justify-content: center; gap: 4px; background: ${accentBg}; color: ${accentText}; border: none; padding: 6px 12px; border-radius: 8px; font-size: 12px; font-weight: 500; cursor: pointer; transition: all 0.15s ease; line-height: 1.4; }
|
|
410
|
+
.ihooman-history-new:hover { opacity: 0.85; }
|
|
370
411
|
.ihooman-history-new svg { width: 12px; height: 12px; flex-shrink: 0; }
|
|
371
412
|
.ihooman-history-list { flex: 1; overflow-y: auto; padding: 8px; overscroll-behavior: contain; }
|
|
372
|
-
.ihooman-history-item { padding: 12px; border: 1px solid ${borderColor}; border-radius:
|
|
373
|
-
.ihooman-history-item:hover { background: ${
|
|
374
|
-
.ihooman-history-item.active { background: ${isDark ? '
|
|
413
|
+
.ihooman-history-item { padding: 12px; border: 1px solid ${borderColor}; border-radius: 10px; margin-bottom: 6px; cursor: pointer; transition: all 0.15s ease; background: ${bgColor}; }
|
|
414
|
+
.ihooman-history-item:hover { background: ${hoverBg}; }
|
|
415
|
+
.ihooman-history-item.active { background: ${hoverBg}; border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
|
|
375
416
|
.ihooman-history-preview { font-size: 13px; color: ${textColor}; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
376
417
|
.ihooman-history-meta { font-size: 11px; color: ${mutedColor}; margin-top: 4px; display: flex; justify-content: space-between; }
|
|
377
|
-
.ihooman-history-empty { padding: 40px; text-align: center; color: ${mutedColor}; font-size:
|
|
378
|
-
|
|
418
|
+
.ihooman-history-empty { padding: 40px; text-align: center; color: ${mutedColor}; font-size: 13px; }
|
|
419
|
+
|
|
420
|
+
/* ── Preset Questions ── */
|
|
421
|
+
.ihooman-preset-questions { padding: 10px 16px; display: flex; flex-wrap: wrap; gap: 6px; background: ${bgColor}; border-top: 1px solid ${borderSubtle}; }
|
|
379
422
|
.ihooman-preset-questions:empty { display: none; }
|
|
380
423
|
.ihooman-preset-questions.hidden { display: none; }
|
|
381
|
-
|
|
424
|
+
|
|
425
|
+
/* ── Proactive Toast ── */
|
|
426
|
+
.ihooman-proactive-toast { position: fixed; ${positionRight ? 'right: 20px' : 'left: 20px'}; ${positionBottom ? 'bottom: 84px' : 'top: 84px'}; max-width: 320px; padding: 16px; background: ${bgElevated}; border-radius: 14px; box-shadow: ${shadowLg}; z-index: ${(zIndex ?? 9999) - 2}; opacity: 0; visibility: hidden; transform: translateY(8px); transition: all 0.2s ease-out; border: 1px solid ${borderColor}; }
|
|
382
427
|
.ihooman-proactive-toast.show { opacity: 1; visibility: visible; transform: translateY(0); }
|
|
383
|
-
.ihooman-proactive-toast-content { font-size: 14px; color: ${textColor}; margin-bottom: 12px; }
|
|
428
|
+
.ihooman-proactive-toast-content { font-size: 14px; color: ${textColor}; margin-bottom: 12px; line-height: 1.5; }
|
|
384
429
|
.ihooman-proactive-toast-actions { display: flex; gap: 8px; }
|
|
385
|
-
.ihooman-proactive-toast-btn { display: inline-flex; align-items: center; justify-content: center; padding: 8px 16px; border-radius:
|
|
386
|
-
.ihooman-proactive-toast-btn.primary { background:
|
|
387
|
-
.ihooman-proactive-toast-btn.primary:hover { opacity: 0.
|
|
388
|
-
.ihooman-proactive-toast-btn.secondary { background: transparent; color: ${
|
|
389
|
-
.ihooman-proactive-toast-btn.secondary:hover { background: ${
|
|
390
|
-
|
|
430
|
+
.ihooman-proactive-toast-btn { display: inline-flex; align-items: center; justify-content: center; padding: 8px 16px; border-radius: 8px; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.15s ease; line-height: 1.4; }
|
|
431
|
+
.ihooman-proactive-toast-btn.primary { background: ${accentBg}; color: ${accentText}; border: none; }
|
|
432
|
+
.ihooman-proactive-toast-btn.primary:hover { opacity: 0.85; }
|
|
433
|
+
.ihooman-proactive-toast-btn.secondary { background: transparent; color: ${textSecondary}; border: 1px solid ${borderColor}; }
|
|
434
|
+
.ihooman-proactive-toast-btn.secondary:hover { background: ${hoverBg}; }
|
|
435
|
+
|
|
436
|
+
/* ── Survey View ── */
|
|
437
|
+
.ihooman-survey-view { display: none; flex-direction: column; padding: 24px; gap: 16px; background: ${bgColor}; flex: 1; align-items: center; justify-content: center; }
|
|
391
438
|
.ihooman-survey-view.show { display: flex; }
|
|
392
|
-
.ihooman-survey-question { font-size: 16px; font-weight: 600; color: ${textColor}; text-align: center; }
|
|
439
|
+
.ihooman-survey-question { font-size: 16px; font-weight: 600; color: ${textColor}; text-align: center; letter-spacing: -0.01em; }
|
|
393
440
|
.ihooman-survey-stars { display: flex; gap: 8px; }
|
|
394
|
-
.ihooman-survey-star { width:
|
|
441
|
+
.ihooman-survey-star { width: 36px; height: 36px; cursor: pointer; color: ${mutedColor}; transition: all 0.15s ease; }
|
|
395
442
|
.ihooman-survey-star:hover, .ihooman-survey-star.active { color: #fbbf24; transform: scale(1.1); }
|
|
396
443
|
.ihooman-survey-star svg { width: 100%; height: 100%; }
|
|
397
|
-
.ihooman-survey-comment { width: 100%; padding: 12px; border: 1px solid ${borderColor}; border-radius:
|
|
398
|
-
.ihooman-survey-
|
|
399
|
-
.ihooman-survey-submit:
|
|
444
|
+
.ihooman-survey-comment { width: 100%; padding: 12px; border: 1px solid ${borderColor}; border-radius: 10px; font-size: 14px; font-family: inherit; resize: none; min-height: 80px; background: ${inputBg}; color: ${textColor}; outline: none; }
|
|
445
|
+
.ihooman-survey-comment:focus { border-color: ${isDark ? '#3f3f46' : '#a1a1aa'}; }
|
|
446
|
+
.ihooman-survey-submit { display: inline-flex; align-items: center; justify-content: center; padding: 10px 20px; background: ${accentBg}; color: ${accentText}; border: none; border-radius: 8px; font-size: 13px; font-weight: 500; cursor: pointer; line-height: 1.4; transition: all 0.15s ease; }
|
|
447
|
+
.ihooman-survey-submit:hover { opacity: 0.85; }
|
|
400
448
|
.ihooman-survey-skip { display: inline-flex; align-items: center; justify-content: center; padding: 8px 16px; background: transparent; color: ${mutedColor}; border: none; font-size: 12px; cursor: pointer; line-height: 1.4; }
|
|
401
449
|
.ihooman-survey-skip:hover { color: ${textColor}; }
|
|
402
|
-
|
|
450
|
+
|
|
451
|
+
/* ── Feedback ── */
|
|
452
|
+
.ihooman-feedback-btns { display: flex; gap: 4px; margin-top: 4px; }
|
|
403
453
|
.ihooman-feedback-btn svg { width: 12px; height: 12px; }
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
.ihooman-carousel
|
|
454
|
+
|
|
455
|
+
/* ── Carousel ── */
|
|
456
|
+
.ihooman-carousel { display: flex; gap: 10px; overflow-x: auto; padding: 8px 0; scroll-snap-type: x mandatory; }
|
|
457
|
+
.ihooman-carousel::-webkit-scrollbar { height: 3px; }
|
|
458
|
+
.ihooman-carousel::-webkit-scrollbar-thumb { background: ${isDark ? '#27272a' : '#d4d4d8'}; border-radius: 2px; }
|
|
459
|
+
.ihooman-carousel-card { min-width: 200px; max-width: 250px; border: 1px solid ${borderColor}; border-radius: 12px; overflow: hidden; scroll-snap-align: start; background: ${bgElevated}; }
|
|
407
460
|
.ihooman-carousel-card img { width: 100%; height: 120px; object-fit: cover; }
|
|
408
461
|
.ihooman-carousel-card-content { padding: 12px; }
|
|
409
|
-
.ihooman-carousel-card-title { font-size:
|
|
410
|
-
.ihooman-carousel-card-desc { font-size: 12px; color: ${
|
|
462
|
+
.ihooman-carousel-card-title { font-size: 13px; font-weight: 600; color: ${textColor}; margin-bottom: 4px; }
|
|
463
|
+
.ihooman-carousel-card-desc { font-size: 12px; color: ${textSecondary}; margin-bottom: 8px; }
|
|
411
464
|
.ihooman-carousel-card-btns { display: flex; flex-direction: column; gap: 6px; }
|
|
465
|
+
|
|
466
|
+
/* ── Quick Replies ── */
|
|
412
467
|
.ihooman-quick-replies { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
|
|
413
|
-
|
|
468
|
+
|
|
469
|
+
/* ── Responsive ── */
|
|
470
|
+
@media (max-width: 480px) { .ihooman-window { width: calc(100vw - 16px); height: calc(100vh - 100px); min-height: 400px; max-height: calc(100vh - 100px); left: 8px; right: 8px; bottom: 80px; } .ihooman-toggle { ${positionRight ? 'right: 16px' : 'left: 16px'}; bottom: 16px; } .ihooman-proactive-toast { left: 8px; right: 8px; max-width: none; } }
|
|
414
471
|
`;
|
|
415
472
|
}
|
|
416
473
|
|
|
@@ -457,9 +514,9 @@ function createWidget(): void {
|
|
|
457
514
|
<div class="ihooman-window" role="dialog" aria-label="Chat window">
|
|
458
515
|
<div class="ihooman-container">
|
|
459
516
|
<div class="ihooman-header">
|
|
460
|
-
<div class="ihooman-header-avatar">${config.avatarUrl ? `<img src="${escapeHtml(config.avatarUrl)}" alt="
|
|
517
|
+
<div class="ihooman-header-avatar">${config.avatarUrl ? `<img src="${escapeHtml(config.avatarUrl)}" alt="Assistant">` : icons.sparkle}</div>
|
|
461
518
|
<div class="ihooman-header-info">
|
|
462
|
-
<div class="ihooman-header-title">${escapeHtml(config.title || '
|
|
519
|
+
<div class="ihooman-header-title">${escapeHtml(config.title || 'AI Assistant')}</div>
|
|
463
520
|
<div class="ihooman-header-status"><span class="ihooman-status-dot"></span><span class="ihooman-status-text">Online</span></div>
|
|
464
521
|
</div>
|
|
465
522
|
<div class="ihooman-header-actions">
|
|
@@ -481,7 +538,7 @@ function createWidget(): void {
|
|
|
481
538
|
</div>
|
|
482
539
|
</div>
|
|
483
540
|
<div class="ihooman-ticket-view">
|
|
484
|
-
<h4 class="ihooman-ticket-title"
|
|
541
|
+
<h4 class="ihooman-ticket-title">Submit a Ticket</h4>
|
|
485
542
|
<p class="ihooman-ticket-subtitle">We'll get back to you via email</p>
|
|
486
543
|
<input class="ihooman-ticket-input" id="ihooman-ticket-name" placeholder="Your name" required>
|
|
487
544
|
<input class="ihooman-ticket-input" id="ihooman-ticket-email" type="email" placeholder="Your email" required>
|
|
@@ -990,6 +1047,8 @@ async function handleRequestLiveAgent(): Promise<void> {
|
|
|
990
1047
|
function startLiveAgentPolling(): void {
|
|
991
1048
|
if (liveAgentPollInterval) return;
|
|
992
1049
|
|
|
1050
|
+
let agentConnected = false;
|
|
1051
|
+
|
|
993
1052
|
liveAgentPollInterval = setInterval(async () => {
|
|
994
1053
|
if (!state.sessionId || !isLiveAgentMode) {
|
|
995
1054
|
stopLiveAgentPolling();
|
|
@@ -1006,6 +1065,12 @@ function startLiveAgentPolling(): void {
|
|
|
1006
1065
|
// Check both ticket_status and conversation_status for agent handling
|
|
1007
1066
|
if (data.ticket_status === 'in_progress' || data.conversation_status === 'active') {
|
|
1008
1067
|
updateStatusBar('connected', '🟢 Connected to live agent');
|
|
1068
|
+
// Agent is connected — stop polling, WebSocket handles real-time updates.
|
|
1069
|
+
// Status changes (close/resolve) will come through WebSocket messages.
|
|
1070
|
+
if (!agentConnected) {
|
|
1071
|
+
agentConnected = true;
|
|
1072
|
+
stopLiveAgentPolling();
|
|
1073
|
+
}
|
|
1009
1074
|
} else if (data.ticket_status === 'open') {
|
|
1010
1075
|
updateStatusBar('waiting', data.position_in_queue > 1
|
|
1011
1076
|
? `⏳ Waiting for agent (Position: #${data.position_in_queue})`
|
|
@@ -1020,7 +1085,7 @@ function startLiveAgentPolling(): void {
|
|
|
1020
1085
|
}
|
|
1021
1086
|
}
|
|
1022
1087
|
} catch { /* ignore */ }
|
|
1023
|
-
},
|
|
1088
|
+
}, 15000);
|
|
1024
1089
|
}
|
|
1025
1090
|
|
|
1026
1091
|
function stopLiveAgentPolling(): void {
|
|
@@ -1126,7 +1191,7 @@ function showTyping(): void {
|
|
|
1126
1191
|
|
|
1127
1192
|
const typing = document.createElement('div');
|
|
1128
1193
|
typing.className = 'ihooman-typing';
|
|
1129
|
-
typing.innerHTML = `<div class="ihooman-typing-dots"><span class="ihooman-typing-dot"></span><span class="ihooman-typing-dot"></span><span class="ihooman-typing-dot"></span></div>`;
|
|
1194
|
+
typing.innerHTML = `<span class="ihooman-typing-shimmer">Thinking...</span><div class="ihooman-typing-dots"><span class="ihooman-typing-dot"></span><span class="ihooman-typing-dot"></span><span class="ihooman-typing-dot"></span></div>`;
|
|
1130
1195
|
elements.messages.appendChild(typing);
|
|
1131
1196
|
elements.messages.scrollTop = elements.messages.scrollHeight;
|
|
1132
1197
|
}
|
|
@@ -1148,7 +1213,7 @@ function disableInput(): void {
|
|
|
1148
1213
|
function enableInput(): void {
|
|
1149
1214
|
if (elements.input) {
|
|
1150
1215
|
elements.input.disabled = false;
|
|
1151
|
-
elements.input.placeholder = config.placeholder || '
|
|
1216
|
+
elements.input.placeholder = config.placeholder || 'Send a message...';
|
|
1152
1217
|
}
|
|
1153
1218
|
if (elements.sendBtn) elements.sendBtn.disabled = !elements.input?.value.trim();
|
|
1154
1219
|
if (elements.attachBtn) elements.attachBtn.disabled = false;
|
|
@@ -1473,7 +1538,7 @@ function connectWebSocket(chatEndpoint?: string): void {
|
|
|
1473
1538
|
startHeartbeat();
|
|
1474
1539
|
};
|
|
1475
1540
|
|
|
1476
|
-
ws.onclose = (
|
|
1541
|
+
ws.onclose = (event) => {
|
|
1477
1542
|
state.isConnected = false;
|
|
1478
1543
|
state.connectionStatus = 'disconnected';
|
|
1479
1544
|
updateStatus(false);
|
|
@@ -1485,6 +1550,9 @@ function connectWebSocket(chatEndpoint?: string): void {
|
|
|
1485
1550
|
return;
|
|
1486
1551
|
}
|
|
1487
1552
|
|
|
1553
|
+
// Code 4002 means this connection was replaced by a newer one — don't reconnect
|
|
1554
|
+
if (event.code === 4002) return;
|
|
1555
|
+
|
|
1488
1556
|
if (!state.isOpen) return;
|
|
1489
1557
|
|
|
1490
1558
|
if (reconnectAttempts < maxReconnectAttempts) {
|
|
@@ -1868,11 +1936,10 @@ function getFontWeightValue(weight: string): number {
|
|
|
1868
1936
|
}
|
|
1869
1937
|
}
|
|
1870
1938
|
|
|
1871
|
-
// Default button styles - MUST match client-dashboard/src/components/widget/ButtonStylingEditor.tsx
|
|
1872
1939
|
const DEFAULT_BUTTON_STYLES = {
|
|
1873
1940
|
primary: {
|
|
1874
|
-
backgroundColor: '#
|
|
1875
|
-
textColor: '#
|
|
1941
|
+
backgroundColor: '#ededed',
|
|
1942
|
+
textColor: '#09090b',
|
|
1876
1943
|
borderColor: 'transparent',
|
|
1877
1944
|
borderWidth: 0,
|
|
1878
1945
|
borderRadius: 8,
|
|
@@ -1883,8 +1950,8 @@ const DEFAULT_BUTTON_STYLES = {
|
|
|
1883
1950
|
},
|
|
1884
1951
|
secondary: {
|
|
1885
1952
|
backgroundColor: 'transparent',
|
|
1886
|
-
textColor: '#
|
|
1887
|
-
borderColor: '#
|
|
1953
|
+
textColor: '#a1a1aa',
|
|
1954
|
+
borderColor: '#27272a',
|
|
1888
1955
|
borderWidth: 1,
|
|
1889
1956
|
borderRadius: 8,
|
|
1890
1957
|
paddingVertical: 8,
|
|
@@ -1893,9 +1960,9 @@ const DEFAULT_BUTTON_STYLES = {
|
|
|
1893
1960
|
fontWeight: 'medium',
|
|
1894
1961
|
},
|
|
1895
1962
|
presetQuestions: {
|
|
1896
|
-
backgroundColor: '
|
|
1897
|
-
textColor: '#
|
|
1898
|
-
borderColor: '
|
|
1963
|
+
backgroundColor: 'transparent',
|
|
1964
|
+
textColor: '#a1a1aa',
|
|
1965
|
+
borderColor: '#27272a',
|
|
1899
1966
|
borderWidth: 1,
|
|
1900
1967
|
borderRadius: 20,
|
|
1901
1968
|
paddingVertical: 6,
|
|
@@ -1904,9 +1971,9 @@ const DEFAULT_BUTTON_STYLES = {
|
|
|
1904
1971
|
fontWeight: 'medium',
|
|
1905
1972
|
},
|
|
1906
1973
|
quickReplies: {
|
|
1907
|
-
backgroundColor: '#
|
|
1908
|
-
textColor: '#
|
|
1909
|
-
borderColor: '#
|
|
1974
|
+
backgroundColor: '#1a1a1a',
|
|
1975
|
+
textColor: '#a1a1aa',
|
|
1976
|
+
borderColor: '#27272a',
|
|
1910
1977
|
borderWidth: 1,
|
|
1911
1978
|
borderRadius: 16,
|
|
1912
1979
|
paddingVertical: 5,
|
|
@@ -1916,8 +1983,8 @@ const DEFAULT_BUTTON_STYLES = {
|
|
|
1916
1983
|
},
|
|
1917
1984
|
feedback: {
|
|
1918
1985
|
backgroundColor: 'transparent',
|
|
1919
|
-
textColor: '#
|
|
1920
|
-
borderColor: '#
|
|
1986
|
+
textColor: '#52525b',
|
|
1987
|
+
borderColor: '#27272a',
|
|
1921
1988
|
borderWidth: 1,
|
|
1922
1989
|
borderRadius: 6,
|
|
1923
1990
|
paddingVertical: 4,
|
|
@@ -1926,19 +1993,19 @@ const DEFAULT_BUTTON_STYLES = {
|
|
|
1926
1993
|
fontWeight: 'medium',
|
|
1927
1994
|
},
|
|
1928
1995
|
headerActions: {
|
|
1929
|
-
backgroundColor: '
|
|
1930
|
-
textColor: '#
|
|
1996
|
+
backgroundColor: 'transparent',
|
|
1997
|
+
textColor: '#a1a1aa',
|
|
1931
1998
|
borderColor: 'transparent',
|
|
1932
1999
|
borderWidth: 0,
|
|
1933
|
-
borderRadius:
|
|
2000
|
+
borderRadius: 8,
|
|
1934
2001
|
paddingVertical: 6,
|
|
1935
2002
|
paddingHorizontal: 6,
|
|
1936
2003
|
fontSize: 14,
|
|
1937
2004
|
fontWeight: 'medium',
|
|
1938
2005
|
},
|
|
1939
2006
|
escalation: {
|
|
1940
|
-
backgroundColor: '#
|
|
1941
|
-
textColor: '#
|
|
2007
|
+
backgroundColor: '#ededed',
|
|
2008
|
+
textColor: '#09090b',
|
|
1942
2009
|
borderColor: 'transparent',
|
|
1943
2010
|
borderWidth: 0,
|
|
1944
2011
|
borderRadius: 8,
|
|
@@ -1948,21 +2015,21 @@ const DEFAULT_BUTTON_STYLES = {
|
|
|
1948
2015
|
fontWeight: 'medium',
|
|
1949
2016
|
},
|
|
1950
2017
|
cardActions: {
|
|
1951
|
-
backgroundColor: '#
|
|
1952
|
-
textColor: '#
|
|
2018
|
+
backgroundColor: '#ededed',
|
|
2019
|
+
textColor: '#09090b',
|
|
1953
2020
|
borderColor: 'transparent',
|
|
1954
2021
|
borderWidth: 0,
|
|
1955
|
-
borderRadius:
|
|
2022
|
+
borderRadius: 8,
|
|
1956
2023
|
paddingVertical: 6,
|
|
1957
2024
|
paddingHorizontal: 12,
|
|
1958
2025
|
fontSize: 12,
|
|
1959
2026
|
fontWeight: 'medium',
|
|
1960
2027
|
},
|
|
1961
2028
|
toggleButton: {
|
|
1962
|
-
backgroundColor: '#
|
|
1963
|
-
textColor: '#
|
|
1964
|
-
borderColor: '
|
|
1965
|
-
borderWidth:
|
|
2029
|
+
backgroundColor: '#ededed',
|
|
2030
|
+
textColor: '#09090b',
|
|
2031
|
+
borderColor: '#27272a',
|
|
2032
|
+
borderWidth: 1,
|
|
1966
2033
|
borderRadius: 30,
|
|
1967
2034
|
paddingVertical: 0,
|
|
1968
2035
|
paddingHorizontal: 0,
|
|
@@ -1971,7 +2038,7 @@ const DEFAULT_BUTTON_STYLES = {
|
|
|
1971
2038
|
},
|
|
1972
2039
|
attachButton: {
|
|
1973
2040
|
backgroundColor: 'transparent',
|
|
1974
|
-
textColor: '#
|
|
2041
|
+
textColor: '#52525b',
|
|
1975
2042
|
borderColor: 'transparent',
|
|
1976
2043
|
borderWidth: 0,
|
|
1977
2044
|
borderRadius: 8,
|