@pocketping/widget 1.6.0 → 1.8.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/dist/index.js CHANGED
@@ -2,12 +2,42 @@
2
2
  import { render, h as h2 } from "preact";
3
3
 
4
4
  // src/components/ChatWidget.tsx
5
- import { Fragment } from "preact";
6
- import { useState, useEffect, useRef, useCallback } from "preact/hooks";
5
+ import { Fragment as Fragment2 } from "preact";
6
+ import { useState as useState2, useEffect as useEffect2, useRef as useRef2, useCallback } from "preact/hooks";
7
7
 
8
8
  // src/components/styles.ts
9
- function styles(primaryColor, theme) {
9
+ function resolveThemeColor(color, isDark, defaultLight, defaultDark) {
10
+ if (!color) {
11
+ return isDark ? defaultDark : defaultLight;
12
+ }
13
+ if (typeof color === "string") {
14
+ return color;
15
+ }
16
+ return isDark ? color.dark : color.light;
17
+ }
18
+ function styles(options) {
19
+ const { primaryColor, theme, headerColor, footerColor, chatBackground, toggleColor } = options;
10
20
  const isDark = theme === "dark";
21
+ const resolvedHeaderColor = resolveThemeColor(headerColor, isDark, "#008069", "#202c33");
22
+ const resolvedFooterColor = resolveThemeColor(footerColor, isDark, "#f0f2f5", "#202c33");
23
+ const resolvedToggleColor = resolveThemeColor(toggleColor, isDark, "#25d366", "#25d366");
24
+ const resolvedToggleHoverColor = resolvedToggleColor !== "#25d366" ? adjustBrightness(resolvedToggleColor, -10) : "#22c55e";
25
+ const whatsappPattern = isDark ? `url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.03'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E")` : `url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23000000' fill-opacity='0.03'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E")`;
26
+ const dotsPattern = isDark ? `url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='10' cy='10' r='1' fill='%23ffffff' fill-opacity='0.05'/%3E%3C/svg%3E")` : `url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='10' cy='10' r='1' fill='%23000000' fill-opacity='0.05'/%3E%3C/svg%3E")`;
27
+ const resolvedChatBg = resolveThemeColor(chatBackground, isDark, "whatsapp", "whatsapp");
28
+ const chatBgColor = isDark ? "#0b141a" : "#e5ddd5";
29
+ let chatBgImage = whatsappPattern;
30
+ let chatBgSize = "auto";
31
+ if (resolvedChatBg === "plain") {
32
+ chatBgImage = "none";
33
+ } else if (resolvedChatBg === "dots") {
34
+ chatBgImage = dotsPattern;
35
+ } else if (resolvedChatBg === "whatsapp" || !resolvedChatBg) {
36
+ chatBgImage = whatsappPattern;
37
+ } else if (resolvedChatBg.startsWith("http") || resolvedChatBg.startsWith("/") || resolvedChatBg.startsWith("data:")) {
38
+ chatBgImage = `url("${resolvedChatBg}")`;
39
+ chatBgSize = "cover";
40
+ }
11
41
  const colors = {
12
42
  bg: isDark ? "#1f2937" : "#ffffff",
13
43
  bgSecondary: isDark ? "#374151" : "#f3f4f6",
@@ -16,6 +46,13 @@ function styles(primaryColor, theme) {
16
46
  border: isDark ? "#4b5563" : "#e5e7eb",
17
47
  messageBg: isDark ? "#374151" : "#f3f4f6"
18
48
  };
49
+ function adjustBrightness(hex, percent) {
50
+ const num = parseInt(hex.replace("#", ""), 16);
51
+ const r = Math.min(255, Math.max(0, (num >> 16) + percent));
52
+ const g = Math.min(255, Math.max(0, (num >> 8 & 255) + percent));
53
+ const b = Math.min(255, Math.max(0, (num & 255) + percent));
54
+ return "#" + (16777216 + (r << 16) + (g << 8) + b).toString(16).slice(1);
55
+ }
19
56
  return `
20
57
  #pocketping-container {
21
58
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
@@ -24,31 +61,47 @@ function styles(primaryColor, theme) {
24
61
  color: ${colors.text};
25
62
  }
26
63
 
64
+ #pocketping-container,
65
+ #pocketping-container * {
66
+ box-sizing: border-box;
67
+ }
68
+
69
+ #pocketping-container img,
70
+ #pocketping-container video {
71
+ max-width: 100%;
72
+ height: auto;
73
+ }
74
+
27
75
  .pp-toggle {
28
76
  position: fixed;
29
- width: 56px;
30
- height: 56px;
77
+ width: 60px;
78
+ height: 60px;
31
79
  border-radius: 50%;
32
- background: ${primaryColor};
80
+ background: ${resolvedToggleColor};
33
81
  color: white;
34
82
  border: none;
35
83
  cursor: pointer;
36
84
  display: flex;
37
85
  align-items: center;
38
86
  justify-content: center;
39
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
40
- transition: transform 0.2s, box-shadow 0.2s;
87
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1);
88
+ transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
41
89
  z-index: 9999;
42
90
  }
43
91
 
44
92
  .pp-toggle:hover {
45
- transform: scale(1.05);
46
- box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
93
+ transform: scale(1.08);
94
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(0, 0, 0, 0.15);
95
+ background: ${resolvedToggleHoverColor};
96
+ }
97
+
98
+ .pp-toggle:active {
99
+ transform: scale(0.95);
47
100
  }
48
101
 
49
102
  .pp-toggle svg {
50
- width: 24px;
51
- height: 24px;
103
+ width: 28px;
104
+ height: 28px;
52
105
  }
53
106
 
54
107
  .pp-toggle.pp-bottom-right {
@@ -99,13 +152,13 @@ function styles(primaryColor, theme) {
99
152
 
100
153
  .pp-window {
101
154
  position: fixed;
102
- width: 380px;
103
- height: 520px;
155
+ width: 375px;
156
+ height: 550px;
104
157
  max-height: calc(100vh - 100px);
105
158
  max-height: calc(100dvh - 100px);
106
- background: ${colors.bg};
107
- border-radius: 16px;
108
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
159
+ background: ${isDark ? "#111b21" : "#ffffff"};
160
+ border-radius: 12px;
161
+ box-shadow: 0 12px 28px rgba(0, 0, 0, 0.2), 0 4px 10px rgba(0, 0, 0, 0.15);
109
162
  display: flex;
110
163
  flex-direction: column;
111
164
  overflow: hidden;
@@ -114,12 +167,12 @@ function styles(primaryColor, theme) {
114
167
  }
115
168
 
116
169
  .pp-window.pp-bottom-right {
117
- bottom: 88px;
170
+ bottom: 20px;
118
171
  right: 20px;
119
172
  }
120
173
 
121
174
  .pp-window.pp-bottom-left {
122
- bottom: 88px;
175
+ bottom: 20px;
123
176
  left: 20px;
124
177
  }
125
178
 
@@ -128,9 +181,9 @@ function styles(primaryColor, theme) {
128
181
  width: calc(100vw - 20px);
129
182
  height: auto;
130
183
  min-height: 300px;
131
- max-height: calc(100vh - 100px);
132
- max-height: calc(100svh - 100px); /* svh = small viewport, excludes keyboard */
133
- bottom: 80px;
184
+ max-height: calc(100vh - 40px);
185
+ max-height: calc(100svh - 40px); /* svh = small viewport, excludes keyboard */
186
+ bottom: 10px;
134
187
  right: 10px;
135
188
  left: 10px;
136
189
  border-radius: 12px;
@@ -148,35 +201,38 @@ function styles(primaryColor, theme) {
148
201
  display: flex;
149
202
  align-items: center;
150
203
  justify-content: space-between;
151
- padding: 12px 14px;
152
- background: ${primaryColor};
204
+ padding: 10px 16px;
205
+ background: ${resolvedHeaderColor};
153
206
  color: white;
154
207
  }
155
208
 
156
209
  .pp-header-info {
157
210
  display: flex;
158
211
  align-items: center;
159
- gap: 10px;
212
+ gap: 12px;
160
213
  }
161
214
 
162
215
  .pp-avatar {
163
- width: 36px;
164
- height: 36px;
216
+ width: 40px;
217
+ height: 40px;
165
218
  border-radius: 50%;
166
219
  object-fit: cover;
220
+ border: 2px solid rgba(255, 255, 255, 0.2);
167
221
  }
168
222
 
169
223
  .pp-header-title {
170
- font-weight: 600;
171
- font-size: 15px;
224
+ font-weight: 500;
225
+ font-size: 16px;
226
+ letter-spacing: 0.1px;
172
227
  }
173
228
 
174
229
  .pp-header-status {
175
- font-size: 11px;
176
- opacity: 0.85;
230
+ font-size: 13px;
231
+ opacity: 0.9;
177
232
  display: flex;
178
233
  align-items: center;
179
- gap: 4px;
234
+ gap: 5px;
235
+ font-weight: 400;
180
236
  }
181
237
 
182
238
  .pp-status-dot {
@@ -187,7 +243,8 @@ function styles(primaryColor, theme) {
187
243
  }
188
244
 
189
245
  .pp-status-dot.pp-online {
190
- background: #22c55e;
246
+ background: #25d366;
247
+ box-shadow: 0 0 0 2px rgba(37, 211, 102, 0.3);
191
248
  }
192
249
 
193
250
  .pp-close-btn {
@@ -195,13 +252,13 @@ function styles(primaryColor, theme) {
195
252
  border: none;
196
253
  color: white;
197
254
  cursor: pointer;
198
- padding: 4px;
199
- border-radius: 4px;
200
- opacity: 0.8;
201
- transition: opacity 0.2s;
255
+ padding: 8px;
256
+ border-radius: 50%;
257
+ opacity: 0.9;
258
+ transition: opacity 0.2s, background 0.2s;
202
259
  flex-shrink: 0;
203
- width: 28px;
204
- height: 28px;
260
+ width: 36px;
261
+ height: 36px;
205
262
  display: flex;
206
263
  align-items: center;
207
264
  justify-content: center;
@@ -209,157 +266,199 @@ function styles(primaryColor, theme) {
209
266
 
210
267
  .pp-close-btn:hover {
211
268
  opacity: 1;
269
+ background: rgba(255, 255, 255, 0.1);
212
270
  }
213
271
 
214
272
  .pp-close-btn svg {
215
- width: 16px;
216
- height: 16px;
273
+ width: 18px;
274
+ height: 18px;
217
275
  }
218
276
 
219
277
  .pp-messages {
220
278
  flex: 1;
221
279
  overflow-y: auto;
222
- padding: 12px;
280
+ padding: 16px 12px;
223
281
  display: flex;
224
282
  flex-direction: column;
225
- gap: 3px;
283
+ gap: 2px;
284
+ overscroll-behavior: contain;
285
+ -webkit-overflow-scrolling: touch;
286
+ position: relative;
287
+ background: ${chatBgColor};
288
+ background-image: ${chatBgImage};
289
+ background-size: ${chatBgSize};
290
+ background-position: center;
226
291
  }
227
292
 
228
293
  .pp-welcome {
229
294
  text-align: center;
230
- color: ${colors.textSecondary};
231
- padding: 24px;
232
- font-size: 13px;
295
+ color: ${isDark ? "#8696a0" : "#667781"};
296
+ padding: 32px 24px;
297
+ font-size: 14px;
298
+ line-height: 1.5;
299
+ background: ${isDark ? "rgba(17, 27, 33, 0.9)" : "rgba(255, 255, 255, 0.95)"};
300
+ margin: 12px;
301
+ border-radius: 8px;
302
+ box-shadow: 0 1px 0.5px rgba(0, 0, 0, 0.13);
233
303
  }
234
304
 
235
305
  .pp-date-separator {
236
306
  display: flex;
237
307
  align-items: center;
238
308
  justify-content: center;
239
- margin: 16px 0 12px;
309
+ margin: 12px 0;
240
310
  }
241
311
 
242
312
  .pp-date-separator span {
243
- background: ${colors.bgSecondary};
244
- color: ${colors.textSecondary};
245
- font-size: 11px;
246
- padding: 4px 12px;
247
- border-radius: 12px;
248
- font-weight: 500;
313
+ background: ${isDark ? "rgba(17, 27, 33, 0.9)" : "rgba(255, 255, 255, 0.95)"};
314
+ color: ${isDark ? "#8696a0" : "#54656f"};
315
+ font-size: 12px;
316
+ padding: 6px 12px;
317
+ border-radius: 8px;
318
+ font-weight: 400;
319
+ box-shadow: 0 1px 0.5px rgba(0, 0, 0, 0.13);
320
+ text-transform: uppercase;
321
+ letter-spacing: 0.3px;
249
322
  }
250
323
 
251
- .pp-message {
252
- max-width: 85%;
253
- padding: 6px 10px;
254
- border-radius: 12px;
255
- word-wrap: break-word;
324
+ /* Swipe container for mobile actions */
325
+ .pp-message-swipe-container {
256
326
  position: relative;
257
- user-select: text;
258
- -webkit-user-select: text;
259
- font-size: 14px;
260
- line-height: 1.35;
327
+ display: flex;
328
+ align-items: stretch;
329
+ overflow: visible;
330
+ touch-action: pan-y;
331
+ }
332
+
333
+ .pp-swipe-left {
334
+ justify-content: flex-end;
335
+ }
336
+
337
+ .pp-swipe-right {
338
+ justify-content: flex-start;
261
339
  }
262
340
 
263
- /* Hover actions container - positioned above message (Slack style) */
264
- .pp-message-actions {
341
+ .pp-swipe-actions {
265
342
  position: absolute;
266
- top: -28px;
267
- display: flex;
268
- gap: 2px;
269
- background: ${colors.bg};
270
- border: 1px solid ${colors.border};
271
- border-radius: 6px;
272
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
273
- padding: 2px;
343
+ top: 0;
344
+ bottom: 0;
345
+ display: none; /* Hidden by default - only show on mobile with touch */
346
+ align-items: center;
347
+ gap: 4px;
274
348
  opacity: 0;
275
- animation: pp-actions-fade-in 0.12s ease forwards;
276
- z-index: 10;
277
- /* Reset color inheritance from message */
278
- color: ${colors.textSecondary};
349
+ pointer-events: none;
279
350
  }
280
351
 
281
- @keyframes pp-actions-fade-in {
282
- from { opacity: 0; transform: translateY(4px); }
283
- to { opacity: 1; transform: translateY(0); }
352
+ /* Only show swipe actions on touch devices */
353
+ @media (hover: none) and (pointer: coarse) {
354
+ .pp-swipe-actions {
355
+ display: flex;
356
+ }
284
357
  }
285
358
 
286
- /* Visitor messages: actions aligned right */
287
- .pp-actions-left {
288
- right: 0;
359
+ .pp-swipe-left .pp-swipe-actions {
360
+ right: -80px; /* Hidden off-screen to the right */
361
+ left: auto;
362
+ padding-right: 8px;
289
363
  }
290
364
 
291
- /* Operator messages: actions aligned left */
292
- .pp-actions-right {
293
- left: 0;
365
+ .pp-swipe-right .pp-swipe-actions {
366
+ left: -80px; /* Hidden off-screen to the left */
367
+ right: auto;
368
+ padding-left: 8px;
294
369
  }
295
370
 
296
- .pp-message-actions .pp-action-btn {
297
- width: 24px;
298
- height: 24px;
371
+ .pp-swipe-action {
372
+ width: 32px;
373
+ height: 32px;
299
374
  border: none;
300
- background: transparent;
301
- border-radius: 4px;
375
+ border-radius: 50%;
302
376
  cursor: pointer;
303
377
  display: flex;
304
378
  align-items: center;
305
379
  justify-content: center;
306
- color: ${colors.textSecondary} !important;
307
- transition: background 0.1s, color 0.1s;
308
- }
309
-
310
- .pp-message-actions .pp-action-btn:hover {
311
- background: ${colors.bgSecondary};
312
- color: ${colors.text} !important;
313
- }
314
-
315
- .pp-message-actions .pp-action-btn svg {
316
- width: 14px;
317
- height: 14px;
318
- stroke: ${colors.textSecondary};
319
- }
320
-
321
- .pp-message-actions .pp-action-btn:hover svg {
322
- stroke: ${colors.text};
380
+ opacity: 0.9;
323
381
  }
324
382
 
325
- .pp-message-actions .pp-action-delete:hover {
326
- background: #fef2f2;
383
+ .pp-swipe-action svg {
384
+ width: 16px;
385
+ height: 16px;
327
386
  }
328
387
 
329
- .pp-message-actions .pp-action-delete:hover svg {
330
- stroke: #ef4444;
388
+ .pp-swipe-reply {
389
+ background: ${primaryColor};
331
390
  }
332
391
 
333
- .pp-theme-dark .pp-message-actions .pp-action-delete:hover {
334
- background: #7f1d1d;
392
+ .pp-swipe-edit {
393
+ background: #3b82f6;
335
394
  }
336
395
 
337
- .pp-theme-dark .pp-message-actions .pp-action-delete:hover svg {
338
- stroke: #fca5a5;
396
+ .pp-swipe-delete {
397
+ background: #ef4444;
339
398
  }
340
399
 
341
- /* Hide hover actions on mobile */
342
- @media (hover: none) and (pointer: coarse) {
343
- .pp-message-actions {
344
- display: none;
345
- }
400
+ .pp-message {
401
+ max-width: 80%;
402
+ padding: 6px 8px 6px 9px;
403
+ border-radius: 8px;
404
+ word-wrap: break-word;
405
+ overflow-wrap: break-word;
406
+ position: relative;
407
+ user-select: text;
408
+ -webkit-user-select: text;
409
+ font-size: 14.2px;
410
+ line-height: 1.4;
411
+ display: block; /* Block for proper float behavior */
412
+ will-change: transform;
413
+ box-shadow: 0 1px 0.5px rgba(0, 0, 0, 0.13);
346
414
  }
347
415
 
348
416
  .pp-message-visitor {
349
417
  align-self: flex-end;
350
- background: ${primaryColor};
351
- color: white;
352
- border-bottom-right-radius: 3px;
353
- margin-left: 32px;
418
+ background: ${isDark ? "#005c4b" : "#d9fdd3"};
419
+ color: ${isDark ? "#e9edef" : "#111b21"};
420
+ border-top-right-radius: 8px;
421
+ border-top-left-radius: 8px;
422
+ border-bottom-left-radius: 8px;
423
+ border-bottom-right-radius: 0;
424
+ margin-left: 48px;
425
+ }
426
+
427
+ /* WhatsApp-style tail for visitor messages */
428
+ .pp-message-visitor::after {
429
+ content: '';
430
+ position: absolute;
431
+ right: -7px;
432
+ bottom: 0;
433
+ width: 8px;
434
+ height: 13px;
435
+ background: ${isDark ? "#005c4b" : "#d9fdd3"};
436
+ clip-path: path('M 0 0 L 0 13 L 8 13 Q 2 10 0 0');
354
437
  }
355
438
 
356
439
  .pp-message-operator,
357
440
  .pp-message-ai {
358
441
  align-self: flex-start;
359
- background: ${colors.messageBg};
360
- color: ${colors.text};
361
- border-bottom-left-radius: 3px;
362
- margin-right: 32px;
442
+ background: ${isDark ? "#202c33" : "#ffffff"};
443
+ color: ${isDark ? "#e9edef" : "#111b21"};
444
+ border-top-right-radius: 8px;
445
+ border-top-left-radius: 8px;
446
+ border-bottom-right-radius: 8px;
447
+ border-bottom-left-radius: 0;
448
+ margin-right: 48px;
449
+ }
450
+
451
+ /* WhatsApp-style tail for operator messages */
452
+ .pp-message-operator::after,
453
+ .pp-message-ai::after {
454
+ content: '';
455
+ position: absolute;
456
+ left: -7px;
457
+ bottom: 0;
458
+ width: 8px;
459
+ height: 13px;
460
+ background: ${isDark ? "#202c33" : "#ffffff"};
461
+ clip-path: path('M 8 0 L 8 13 L 0 13 Q 6 10 8 0');
363
462
  }
364
463
 
365
464
  /* Add spacing between different senders */
@@ -374,23 +473,38 @@ function styles(primaryColor, theme) {
374
473
  display: inline;
375
474
  }
376
475
 
476
+ /* WhatsApp-style inline timestamp - floats to the right */
377
477
  .pp-message-time {
378
- font-size: 10px;
379
- opacity: 0.6;
478
+ font-size: 11px;
380
479
  display: inline-flex;
381
480
  align-items: center;
382
481
  gap: 3px;
383
482
  float: right;
384
- margin-left: 8px;
483
+ margin: 3px 0 0 12px;
484
+ color: ${isDark ? "rgba(255,255,255,0.6)" : "rgba(0,0,0,0.45)"};
485
+ white-space: nowrap;
486
+ }
487
+
488
+ .pp-message-visitor .pp-message-time {
489
+ color: ${isDark ? "rgba(255,255,255,0.7)" : "rgba(0,0,0,0.45)"};
490
+ }
491
+
492
+ /* Timestamp for attachment-only messages */
493
+ .pp-attachment-time {
494
+ float: none;
495
+ display: flex;
496
+ justify-content: flex-end;
385
497
  margin-top: 4px;
386
498
  }
387
499
 
388
500
  .pp-ai-badge {
389
- background: rgba(0, 0, 0, 0.1);
390
- padding: 1px 4px;
501
+ background: ${isDark ? "rgba(255,255,255,0.15)" : "rgba(0, 0, 0, 0.08)"};
502
+ padding: 2px 5px;
391
503
  border-radius: 4px;
392
- font-size: 10px;
504
+ font-size: 9px;
393
505
  font-weight: 600;
506
+ text-transform: uppercase;
507
+ letter-spacing: 0.3px;
394
508
  }
395
509
 
396
510
  .pp-status {
@@ -406,11 +520,11 @@ function styles(primaryColor, theme) {
406
520
 
407
521
  .pp-check,
408
522
  .pp-check-double {
409
- stroke: rgba(255, 255, 255, 0.7);
523
+ stroke: ${isDark ? "rgba(255, 255, 255, 0.5)" : "rgba(0, 0, 0, 0.35)"};
410
524
  }
411
525
 
412
526
  .pp-check-read {
413
- stroke: #34b7f1;
527
+ stroke: #53bdeb;
414
528
  }
415
529
 
416
530
  .pp-status-sending .pp-check {
@@ -419,14 +533,15 @@ function styles(primaryColor, theme) {
419
533
 
420
534
  .pp-typing {
421
535
  display: flex;
422
- gap: 3px;
423
- padding: 8px 12px;
536
+ gap: 4px;
537
+ padding: 12px 14px;
538
+ align-items: center;
424
539
  }
425
540
 
426
541
  .pp-typing span {
427
- width: 6px;
428
- height: 6px;
429
- background: ${colors.textSecondary};
542
+ width: 7px;
543
+ height: 7px;
544
+ background: ${isDark ? "#8696a0" : "#667781"};
430
545
  border-radius: 50%;
431
546
  animation: pp-bounce 1.4s infinite ease-in-out both;
432
547
  }
@@ -441,57 +556,56 @@ function styles(primaryColor, theme) {
441
556
 
442
557
  .pp-input-form {
443
558
  display: flex;
444
- padding: 10px 12px;
559
+ padding: 8px 10px;
445
560
  gap: 8px;
446
- border-top: 1px solid ${colors.border};
561
+ background: ${resolvedFooterColor};
447
562
  align-items: center;
448
563
  }
449
564
 
450
565
  .pp-input {
451
566
  flex: 1;
452
567
  min-width: 0;
453
- height: 40px;
454
- line-height: 40px;
455
- padding: 0 16px;
456
- border: 1px solid ${colors.border};
457
- border-radius: 20px;
458
- background: ${colors.bg};
459
- color: ${colors.text};
460
- font-size: 14px;
568
+ height: 42px;
569
+ line-height: 42px;
570
+ padding: 0 14px;
571
+ border: none;
572
+ border-radius: 8px;
573
+ background: ${isDark ? "#2a3942" : "#ffffff"};
574
+ color: ${isDark ? "#e9edef" : "#111b21"};
575
+ font-size: 15px;
461
576
  outline: none;
462
- transition: border-color 0.2s;
463
577
  box-sizing: border-box;
464
578
  margin: 0;
465
579
  }
466
580
 
467
581
  .pp-input:focus {
468
- border-color: ${primaryColor};
582
+ outline: none;
469
583
  }
470
584
 
471
585
  .pp-input::placeholder {
472
- color: ${colors.textSecondary};
586
+ color: ${isDark ? "#8696a0" : "#667781"};
473
587
  }
474
588
 
475
589
  .pp-send-btn {
476
- width: 40px;
477
- height: 40px;
478
- min-width: 40px;
590
+ width: 42px;
591
+ height: 42px;
592
+ min-width: 42px;
479
593
  border-radius: 50%;
480
- background: ${primaryColor};
594
+ background: #00a884;
481
595
  color: white;
482
596
  border: none;
483
597
  cursor: pointer;
484
598
  display: flex;
485
599
  align-items: center;
486
600
  justify-content: center;
487
- transition: opacity 0.2s, transform 0.1s;
601
+ transition: background 0.2s, transform 0.1s;
488
602
  flex-shrink: 0;
489
603
  margin: 0;
490
604
  padding: 0;
491
605
  }
492
606
 
493
607
  .pp-send-btn:not(:disabled):hover {
494
- transform: scale(1.05);
608
+ background: #008f72;
495
609
  }
496
610
 
497
611
  .pp-send-btn:not(:disabled):active {
@@ -499,27 +613,27 @@ function styles(primaryColor, theme) {
499
613
  }
500
614
 
501
615
  .pp-send-btn:disabled {
502
- opacity: 0.5;
616
+ background: ${isDark ? "#3b4a54" : "#b3b3b3"};
503
617
  cursor: not-allowed;
504
618
  }
505
619
 
506
620
  .pp-send-btn svg {
507
- width: 18px;
508
- height: 18px;
621
+ width: 20px;
622
+ height: 20px;
509
623
  }
510
624
 
511
625
  .pp-footer {
512
626
  text-align: center;
513
- padding: 8px;
514
- font-size: 11px;
515
- color: ${colors.textSecondary};
516
- border-top: 1px solid ${colors.border};
517
- opacity: 0.7;
627
+ padding: 6px 8px;
628
+ font-size: 10px;
629
+ color: ${isDark ? "#8696a0" : "#667781"};
630
+ background: ${resolvedFooterColor};
518
631
  }
519
632
 
520
633
  .pp-footer a {
521
- color: ${primaryColor};
634
+ color: ${isDark ? "#00a884" : "#008069"};
522
635
  text-decoration: none;
636
+ font-weight: 500;
523
637
  }
524
638
 
525
639
  .pp-footer a:hover {
@@ -541,26 +655,26 @@ function styles(primaryColor, theme) {
541
655
  }
542
656
 
543
657
  .pp-attach-btn {
544
- width: 40px;
545
- height: 40px;
546
- min-width: 40px;
658
+ width: 42px;
659
+ height: 42px;
660
+ min-width: 42px;
547
661
  border-radius: 50%;
548
662
  background: transparent;
549
- color: ${colors.textSecondary};
550
- border: 1px solid ${colors.border};
663
+ color: ${isDark ? "#8696a0" : "#54656f"};
664
+ border: none;
551
665
  cursor: pointer;
552
666
  display: flex;
553
667
  align-items: center;
554
668
  justify-content: center;
555
669
  margin: 0;
556
670
  padding: 0;
557
- transition: color 0.2s, border-color 0.2s;
671
+ transition: color 0.2s, background 0.2s;
558
672
  flex-shrink: 0;
559
673
  }
560
674
 
561
675
  .pp-attach-btn:hover:not(:disabled) {
562
- color: ${primaryColor};
563
- border-color: ${primaryColor};
676
+ color: ${isDark ? "#aebac1" : "#3b4a54"};
677
+ background: ${isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.05)"};
564
678
  }
565
679
 
566
680
  .pp-attach-btn:disabled {
@@ -569,28 +683,27 @@ function styles(primaryColor, theme) {
569
683
  }
570
684
 
571
685
  .pp-attach-btn svg {
572
- width: 18px;
573
- height: 18px;
686
+ width: 22px;
687
+ height: 22px;
574
688
  }
575
689
 
576
690
  .pp-attachments-preview {
577
691
  display: flex;
578
692
  gap: 8px;
579
- padding: 8px 12px;
580
- border-top: 1px solid ${colors.border};
693
+ padding: 10px 12px;
581
694
  overflow-x: auto;
582
- background: ${colors.bgSecondary};
695
+ background: ${resolvedFooterColor};
583
696
  }
584
697
 
585
698
  .pp-attachment-preview {
586
699
  position: relative;
587
- width: 60px;
588
- height: 60px;
589
- border-radius: 8px;
700
+ width: 64px;
701
+ height: 64px;
702
+ border-radius: 10px;
590
703
  overflow: hidden;
591
704
  flex-shrink: 0;
592
- background: ${colors.bg};
593
- border: 1px solid ${colors.border};
705
+ background: ${isDark ? "#2a3942" : "#ffffff"};
706
+ box-shadow: 0 1px 2px rgba(0,0,0,0.1);
594
707
  }
595
708
 
596
709
  .pp-preview-img {
@@ -674,7 +787,10 @@ function styles(primaryColor, theme) {
674
787
  display: flex;
675
788
  flex-direction: column;
676
789
  gap: 8px;
677
- margin-top: 4px;
790
+ margin-top: 6px;
791
+ max-width: 100%;
792
+ align-items: flex-start;
793
+ flex-shrink: 0;
678
794
  }
679
795
 
680
796
  .pp-attachment {
@@ -685,11 +801,22 @@ function styles(primaryColor, theme) {
685
801
  overflow: hidden;
686
802
  }
687
803
 
804
+ .pp-attachment-image,
805
+ .pp-attachment-video,
806
+ .pp-attachment-audio {
807
+ width: 240px;
808
+ max-width: 100%;
809
+ }
810
+
688
811
  .pp-attachment-image img {
689
- max-width: 200px;
812
+ width: 100% !important;
813
+ height: auto !important;
814
+ max-width: 240px;
690
815
  max-height: 200px;
691
816
  border-radius: 8px;
692
817
  display: block;
818
+ object-fit: cover !important;
819
+ object-position: center;
693
820
  }
694
821
 
695
822
  .pp-attachment-audio {
@@ -699,7 +826,8 @@ function styles(primaryColor, theme) {
699
826
  }
700
827
 
701
828
  .pp-attachment-audio audio {
702
- width: 200px;
829
+ width: 240px;
830
+ max-width: 100%;
703
831
  height: 36px;
704
832
  }
705
833
 
@@ -709,14 +837,18 @@ function styles(primaryColor, theme) {
709
837
  white-space: nowrap;
710
838
  overflow: hidden;
711
839
  text-overflow: ellipsis;
712
- max-width: 200px;
840
+ max-width: 100%;
713
841
  }
714
842
 
715
843
  .pp-attachment-video video {
716
- max-width: 200px;
717
- max-height: 200px;
844
+ width: 100% !important;
845
+ height: auto !important;
846
+ max-width: 240px;
847
+ max-height: none;
718
848
  border-radius: 8px;
719
849
  display: block;
850
+ object-fit: contain !important;
851
+ object-position: center;
720
852
  }
721
853
 
722
854
  .pp-attachment-file {
@@ -765,81 +897,86 @@ function styles(primaryColor, theme) {
765
897
  .pp-drop-overlay {
766
898
  position: absolute;
767
899
  inset: 0;
768
- background: ${isDark ? "rgba(0,0,0,0.9)" : "rgba(255,255,255,0.95)"};
900
+ background: ${isDark ? "rgba(17, 27, 33, 0.95)" : "rgba(255,255,255,0.97)"};
769
901
  display: flex;
770
902
  flex-direction: column;
771
903
  align-items: center;
772
904
  justify-content: center;
773
- gap: 12px;
905
+ gap: 16px;
774
906
  z-index: 100;
775
- border: 3px dashed ${primaryColor};
776
- border-radius: 16px;
907
+ border: 3px dashed #00a884;
908
+ border-radius: 12px;
777
909
  margin: 4px;
778
910
  pointer-events: none;
779
911
  }
780
912
 
781
913
  .pp-drop-icon svg {
782
- width: 48px;
783
- height: 48px;
784
- color: ${primaryColor};
914
+ width: 56px;
915
+ height: 56px;
916
+ color: #00a884;
785
917
  }
786
918
 
787
919
  .pp-drop-text {
788
- font-size: 16px;
920
+ font-size: 17px;
789
921
  font-weight: 500;
790
- color: ${colors.text};
922
+ color: ${isDark ? "#e9edef" : "#111b21"};
791
923
  }
792
924
 
793
925
  /* Message Context Menu */
794
926
  .pp-message-menu {
795
927
  position: fixed;
796
- background: ${colors.bg};
797
- border: 1px solid ${colors.border};
798
- border-radius: 8px;
799
- box-shadow: 0 4px 12px rgba(0,0,0,0.15);
800
- padding: 4px;
928
+ background: ${isDark ? "#233138" : "#ffffff"};
929
+ border: none;
930
+ border-radius: 12px;
931
+ box-shadow: 0 8px 24px rgba(0,0,0,0.2), 0 2px 8px rgba(0,0,0,0.1);
932
+ padding: 6px;
801
933
  z-index: 200;
802
- min-width: 120px;
934
+ min-width: 140px;
803
935
  }
804
936
 
805
937
  .pp-message-menu button {
806
938
  display: flex;
807
939
  align-items: center;
808
- gap: 8px;
940
+ gap: 10px;
809
941
  width: 100%;
810
- padding: 8px 12px;
942
+ padding: 10px 14px;
811
943
  border: none;
812
944
  background: transparent;
813
- color: ${colors.text};
814
- font-size: 13px;
945
+ color: ${isDark ? "#e9edef" : "#111b21"};
946
+ font-size: 14px;
815
947
  cursor: pointer;
816
- border-radius: 4px;
948
+ border-radius: 8px;
817
949
  text-align: left;
950
+ transition: background 0.15s;
818
951
  }
819
952
 
820
953
  .pp-message-menu button:hover {
821
- background: ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"};
954
+ background: ${isDark ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.05)"};
822
955
  }
823
956
 
824
957
  .pp-message-menu button svg {
825
- width: 16px;
826
- height: 16px;
958
+ width: 18px;
959
+ height: 18px;
827
960
  }
828
961
 
829
962
  .pp-menu-delete {
830
963
  color: #ef4444 !important;
831
964
  }
832
965
 
966
+ .pp-menu-delete:hover {
967
+ background: ${isDark ? "rgba(239,68,68,0.15)" : "rgba(239,68,68,0.08)"} !important;
968
+ }
969
+
833
970
  /* Edit Modal */
834
971
  .pp-edit-modal {
835
972
  position: absolute;
836
973
  bottom: 80px;
837
974
  left: 12px;
838
975
  right: 12px;
839
- background: ${colors.bg};
840
- border: 1px solid ${colors.border};
976
+ background: ${isDark ? "#233138" : "#ffffff"};
977
+ border: none;
841
978
  border-radius: 12px;
842
- box-shadow: 0 4px 20px rgba(0,0,0,0.15);
979
+ box-shadow: 0 8px 28px rgba(0,0,0,0.25), 0 2px 8px rgba(0,0,0,0.1);
843
980
  z-index: 150;
844
981
  overflow: hidden;
845
982
  }
@@ -848,17 +985,24 @@ function styles(primaryColor, theme) {
848
985
  display: flex;
849
986
  justify-content: space-between;
850
987
  align-items: center;
851
- padding: 12px 16px;
852
- border-bottom: 1px solid ${colors.border};
988
+ padding: 14px 16px;
989
+ border-bottom: 1px solid ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.08)"};
853
990
  font-weight: 500;
991
+ color: ${isDark ? "#e9edef" : "#111b21"};
854
992
  }
855
993
 
856
994
  .pp-edit-header button {
857
995
  background: transparent;
858
996
  border: none;
859
- color: ${colors.textSecondary};
997
+ color: ${isDark ? "#8696a0" : "#667781"};
860
998
  cursor: pointer;
861
- padding: 4px;
999
+ padding: 6px;
1000
+ border-radius: 50%;
1001
+ transition: background 0.15s;
1002
+ }
1003
+
1004
+ .pp-edit-header button:hover {
1005
+ background: ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"};
862
1006
  }
863
1007
 
864
1008
  .pp-edit-header button svg {
@@ -868,210 +1012,840 @@ function styles(primaryColor, theme) {
868
1012
 
869
1013
  .pp-edit-input {
870
1014
  width: 100%;
871
- padding: 12px 16px;
1015
+ padding: 14px 16px;
872
1016
  border: none;
873
1017
  background: transparent;
874
- color: ${colors.text};
875
- font-size: 14px;
1018
+ color: ${isDark ? "#e9edef" : "#111b21"};
1019
+ font-size: 15px;
876
1020
  resize: none;
877
1021
  min-height: 80px;
878
1022
  outline: none;
1023
+ line-height: 1.5;
1024
+ }
1025
+
1026
+ .pp-edit-input::placeholder {
1027
+ color: ${isDark ? "#8696a0" : "#667781"};
1028
+ }
1029
+
1030
+ .pp-edit-actions {
1031
+ display: flex;
1032
+ justify-content: flex-end;
1033
+ gap: 10px;
1034
+ padding: 12px 16px;
1035
+ border-top: 1px solid ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.08)"};
1036
+ }
1037
+
1038
+ .pp-edit-cancel {
1039
+ padding: 10px 20px;
1040
+ border: none;
1041
+ border-radius: 8px;
1042
+ background: ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"};
1043
+ color: ${isDark ? "#e9edef" : "#111b21"};
1044
+ font-size: 14px;
1045
+ cursor: pointer;
1046
+ transition: background 0.15s;
1047
+ }
1048
+
1049
+ .pp-edit-cancel:hover {
1050
+ background: ${isDark ? "rgba(255,255,255,0.15)" : "rgba(0,0,0,0.08)"};
1051
+ }
1052
+
1053
+ .pp-edit-save {
1054
+ padding: 10px 20px;
1055
+ border: none;
1056
+ border-radius: 8px;
1057
+ background: #00a884;
1058
+ color: white;
1059
+ font-size: 14px;
1060
+ font-weight: 500;
1061
+ cursor: pointer;
1062
+ transition: background 0.15s;
1063
+ }
1064
+
1065
+ .pp-edit-save:hover:not(:disabled) {
1066
+ background: #008f72;
1067
+ }
1068
+
1069
+ .pp-edit-save:disabled {
1070
+ background: ${isDark ? "#3b4a54" : "#b3b3b3"};
1071
+ cursor: not-allowed;
1072
+ }
1073
+
1074
+ /* Reply Preview */
1075
+ .pp-reply-preview {
1076
+ display: flex;
1077
+ align-items: center;
1078
+ gap: 10px;
1079
+ padding: 8px 12px;
1080
+ background: ${resolvedFooterColor};
1081
+ border-left: 4px solid #00a884;
1082
+ }
1083
+
1084
+ .pp-reply-preview-content {
1085
+ flex: 1;
1086
+ min-width: 0;
1087
+ }
1088
+
1089
+ .pp-reply-label {
1090
+ display: block;
1091
+ font-size: 12px;
1092
+ color: #00a884;
1093
+ font-weight: 500;
1094
+ margin-bottom: 2px;
1095
+ }
1096
+
1097
+ .pp-reply-text {
1098
+ display: block;
1099
+ font-size: 13px;
1100
+ color: ${isDark ? "#8696a0" : "#667781"};
1101
+ white-space: nowrap;
1102
+ overflow: hidden;
1103
+ text-overflow: ellipsis;
1104
+ }
1105
+
1106
+ .pp-reply-cancel {
1107
+ background: transparent;
1108
+ border: none;
1109
+ border-radius: 50%;
1110
+ color: ${isDark ? "#8696a0" : "#667781"};
1111
+ cursor: pointer;
1112
+ padding: 0;
1113
+ width: 28px;
1114
+ height: 28px;
1115
+ min-width: 28px;
1116
+ display: flex;
1117
+ align-items: center;
1118
+ justify-content: center;
1119
+ flex-shrink: 0;
1120
+ transition: background 0.15s, color 0.15s;
1121
+ }
1122
+
1123
+ .pp-reply-cancel:hover {
1124
+ background: ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.08)"};
1125
+ color: ${isDark ? "#aebac1" : "#3b4a54"};
1126
+ }
1127
+
1128
+ .pp-reply-cancel svg {
1129
+ width: 16px;
1130
+ height: 16px;
1131
+ }
1132
+
1133
+ /* Reply Quote in Message */
1134
+ .pp-reply-quote {
1135
+ background: ${isDark ? "rgba(0,0,0,0.2)" : "rgba(0,0,0,0.05)"};
1136
+ border-left: 3px solid #00a884;
1137
+ padding: 6px 10px;
1138
+ margin-bottom: 4px;
1139
+ border-radius: 0 6px 6px 0;
1140
+ font-size: 13px;
1141
+ position: relative;
1142
+ z-index: 1;
1143
+ }
1144
+
1145
+ .pp-reply-sender {
1146
+ display: block;
1147
+ font-weight: 500;
1148
+ color: #00a884;
1149
+ margin-bottom: 2px;
1150
+ font-size: 12px;
1151
+ }
1152
+
1153
+ .pp-reply-content {
1154
+ display: block;
1155
+ color: ${isDark ? "#8696a0" : "#667781"};
1156
+ white-space: nowrap;
1157
+ overflow: hidden;
1158
+ text-overflow: ellipsis;
1159
+ }
1160
+
1161
+ /* Clickable reply quote */
1162
+ .pp-reply-quote-clickable {
1163
+ cursor: pointer;
1164
+ transition: background 0.15s;
1165
+ }
1166
+
1167
+ .pp-reply-quote-clickable:hover {
1168
+ background: ${isDark ? "rgba(0,0,0,0.3)" : "rgba(0,0,0,0.08)"};
1169
+ }
1170
+
1171
+ .pp-reply-quote-clickable:active {
1172
+ transform: scale(0.99);
1173
+ }
1174
+
1175
+ /* Reply quote in visitor message bubble needs higher contrast */
1176
+ .pp-message-visitor .pp-reply-quote {
1177
+ background: ${isDark ? "rgba(0,0,0,0.2)" : "rgba(0,0,0,0.08)"};
1178
+ border-left-color: ${isDark ? "rgba(255,255,255,0.5)" : "#00a884"};
1179
+ }
1180
+
1181
+ .pp-message-visitor .pp-reply-quote-clickable:hover {
1182
+ background: ${isDark ? "rgba(0,0,0,0.3)" : "rgba(0,0,0,0.12)"};
1183
+ }
1184
+
1185
+ .pp-message-visitor .pp-reply-sender {
1186
+ color: ${isDark ? "rgba(255,255,255,0.9)" : "#00a884"};
1187
+ }
1188
+
1189
+ .pp-message-visitor .pp-reply-content {
1190
+ color: ${isDark ? "rgba(255,255,255,0.7)" : "rgba(0,0,0,0.6)"};
1191
+ }
1192
+
1193
+ /* Message highlight animation (when scrolling to a message) */
1194
+ .pp-message-highlight {
1195
+ animation: pp-highlight-pulse 1.5s ease-out;
1196
+ }
1197
+
1198
+ @keyframes pp-highlight-pulse {
1199
+ 0% {
1200
+ box-shadow: 0 0 0 0 rgba(0, 168, 132, 0.5);
1201
+ }
1202
+ 30% {
1203
+ box-shadow: 0 0 0 6px rgba(0, 168, 132, 0.25);
1204
+ }
1205
+ 100% {
1206
+ box-shadow: 0 0 0 0 rgba(0, 168, 132, 0);
1207
+ }
1208
+ }
1209
+
1210
+ /* Deleted Message */
1211
+ .pp-message-deleted {
1212
+ opacity: 0.6;
1213
+ }
1214
+
1215
+ .pp-deleted-content {
1216
+ font-style: italic;
1217
+ color: ${colors.textSecondary};
1218
+ display: flex;
1219
+ align-items: center;
1220
+ gap: 4px;
1221
+ }
1222
+
1223
+ .pp-deleted-icon {
1224
+ font-size: 12px;
1225
+ }
1226
+
1227
+ /* Edited Badge */
1228
+ .pp-edited-badge {
1229
+ font-size: 10px;
1230
+ margin-left: 4px;
1231
+ font-style: italic;
1232
+ opacity: 0.7;
1233
+ }
1234
+
1235
+ /* Pre-Chat Form */
1236
+ .pp-prechat {
1237
+ flex: 1;
1238
+ display: flex;
1239
+ flex-direction: column;
1240
+ padding: 24px 20px;
1241
+ overflow-y: auto;
1242
+ background: ${isDark ? "#111b21" : "#ffffff"};
1243
+ }
1244
+
1245
+ .pp-prechat-title {
1246
+ font-size: 20px;
1247
+ font-weight: 600;
1248
+ margin-bottom: 8px;
1249
+ color: ${isDark ? "#e9edef" : "#111b21"};
1250
+ }
1251
+
1252
+ .pp-prechat-subtitle {
1253
+ font-size: 14px;
1254
+ color: ${isDark ? "#8696a0" : "#667781"};
1255
+ margin-bottom: 24px;
1256
+ line-height: 1.5;
1257
+ }
1258
+
1259
+ .pp-prechat-tabs {
1260
+ display: flex;
1261
+ gap: 8px;
1262
+ margin-bottom: 20px;
1263
+ }
1264
+
1265
+ .pp-prechat-tab {
1266
+ flex: 1;
1267
+ padding: 10px;
1268
+ border: 1px solid ${colors.border};
1269
+ border-radius: 8px;
1270
+ background: transparent;
1271
+ color: ${colors.textSecondary};
1272
+ font-size: 13px;
1273
+ cursor: pointer;
1274
+ transition: all 0.2s;
1275
+ display: flex;
1276
+ align-items: center;
1277
+ justify-content: center;
1278
+ gap: 6px;
1279
+ }
1280
+
1281
+ .pp-prechat-tab:hover {
1282
+ background: ${colors.bgSecondary};
1283
+ }
1284
+
1285
+ .pp-prechat-tab.active {
1286
+ background: ${primaryColor}15;
1287
+ border-color: ${primaryColor};
1288
+ color: ${primaryColor};
1289
+ }
1290
+
1291
+ .pp-prechat-tab svg {
1292
+ width: 16px;
1293
+ height: 16px;
1294
+ }
1295
+
1296
+ .pp-prechat-field {
1297
+ margin-bottom: 16px;
1298
+ }
1299
+
1300
+ .pp-prechat-label {
1301
+ display: block;
1302
+ font-size: 12px;
1303
+ font-weight: 500;
1304
+ color: ${colors.textSecondary};
1305
+ margin-bottom: 6px;
1306
+ }
1307
+
1308
+ .pp-prechat-input {
1309
+ width: 100%;
1310
+ height: 44px;
1311
+ padding: 0 14px;
1312
+ border: 1px solid ${colors.border};
1313
+ border-radius: 8px;
1314
+ background: ${colors.bg};
1315
+ color: ${colors.text};
1316
+ font-size: 14px;
1317
+ outline: none;
1318
+ transition: border-color 0.2s;
1319
+ box-sizing: border-box;
1320
+ }
1321
+
1322
+ .pp-prechat-input:focus {
1323
+ border-color: ${primaryColor};
1324
+ }
1325
+
1326
+ .pp-prechat-input::placeholder {
1327
+ color: ${colors.textSecondary};
1328
+ }
1329
+
1330
+ .pp-prechat-input.error {
1331
+ border-color: #ef4444;
1332
+ }
1333
+
1334
+ .pp-prechat-error {
1335
+ color: #ef4444;
1336
+ font-size: 12px;
1337
+ margin-top: 4px;
1338
+ }
1339
+
1340
+ .pp-phone-input-wrapper {
1341
+ display: flex;
1342
+ gap: 8px;
1343
+ }
1344
+
1345
+ .pp-country-select {
1346
+ position: relative;
1347
+ }
1348
+
1349
+ .pp-country-btn {
1350
+ display: flex;
1351
+ align-items: center;
1352
+ gap: 6px;
1353
+ height: 44px;
1354
+ padding: 0 10px;
1355
+ border: 1px solid ${colors.border};
1356
+ border-radius: 8px;
1357
+ background: ${colors.bg};
1358
+ color: ${colors.text};
1359
+ font-size: 14px;
1360
+ cursor: pointer;
1361
+ transition: border-color 0.2s;
1362
+ }
1363
+
1364
+ .pp-country-btn:focus {
1365
+ border-color: ${primaryColor};
1366
+ outline: none;
1367
+ }
1368
+
1369
+ .pp-country-flag {
1370
+ font-size: 18px;
1371
+ line-height: 1;
1372
+ }
1373
+
1374
+ .pp-country-code {
1375
+ font-size: 13px;
1376
+ color: ${colors.textSecondary};
1377
+ }
1378
+
1379
+ .pp-country-chevron {
1380
+ width: 12px;
1381
+ height: 12px;
1382
+ color: ${colors.textSecondary};
1383
+ }
1384
+
1385
+ .pp-country-dropdown {
1386
+ position: absolute;
1387
+ top: calc(100% + 4px);
1388
+ left: 0;
1389
+ width: 280px;
1390
+ max-height: 280px;
1391
+ overflow-y: auto;
1392
+ background: ${colors.bg};
1393
+ border: 1px solid ${colors.border};
1394
+ border-radius: 8px;
1395
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
1396
+ z-index: 100;
879
1397
  }
880
1398
 
881
- .pp-edit-actions {
882
- display: flex;
883
- justify-content: flex-end;
884
- gap: 8px;
885
- padding: 12px 16px;
886
- border-top: 1px solid ${colors.border};
1399
+ .pp-country-search {
1400
+ position: sticky;
1401
+ top: 0;
1402
+ padding: 8px;
1403
+ background: ${colors.bg};
1404
+ border-bottom: 1px solid ${colors.border};
887
1405
  }
888
1406
 
889
- .pp-edit-cancel {
890
- padding: 8px 16px;
1407
+ .pp-country-search-input {
1408
+ width: 100%;
1409
+ height: 36px;
1410
+ padding: 0 12px;
891
1411
  border: 1px solid ${colors.border};
892
1412
  border-radius: 6px;
893
- background: transparent;
1413
+ background: ${colors.bgSecondary};
894
1414
  color: ${colors.text};
895
1415
  font-size: 13px;
896
- cursor: pointer;
1416
+ outline: none;
1417
+ box-sizing: border-box;
897
1418
  }
898
1419
 
899
- .pp-edit-save {
900
- padding: 8px 16px;
901
- border: none;
902
- border-radius: 6px;
903
- background: ${primaryColor};
904
- color: white;
905
- font-size: 13px;
906
- cursor: pointer;
1420
+ .pp-country-search-input:focus {
1421
+ border-color: ${primaryColor};
907
1422
  }
908
1423
 
909
- .pp-edit-save:disabled {
910
- opacity: 0.5;
911
- cursor: not-allowed;
1424
+ .pp-country-list {
1425
+ padding: 4px;
912
1426
  }
913
1427
 
914
- /* Reply Preview */
915
- .pp-reply-preview {
1428
+ .pp-country-option {
916
1429
  display: flex;
917
1430
  align-items: center;
918
- gap: 8px;
919
- padding: 8px 12px;
920
- background: ${isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.03)"};
921
- border-top: 1px solid ${colors.border};
922
- border-left: 3px solid ${primaryColor};
923
- }
924
-
925
- .pp-reply-preview-content {
926
- flex: 1;
927
- min-width: 0;
928
- }
929
-
930
- .pp-reply-label {
931
- display: block;
932
- font-size: 11px;
933
- color: ${primaryColor};
934
- font-weight: 500;
935
- margin-bottom: 2px;
936
- }
937
-
938
- .pp-reply-text {
939
- display: block;
940
- font-size: 12px;
941
- color: ${colors.textSecondary};
942
- white-space: nowrap;
943
- overflow: hidden;
944
- text-overflow: ellipsis;
945
- }
946
-
947
- .pp-reply-cancel {
948
- background: ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"};
949
- border: none;
950
- border-radius: 50%;
951
- color: ${colors.textSecondary};
1431
+ gap: 10px;
1432
+ padding: 10px 12px;
952
1433
  cursor: pointer;
953
- padding: 0;
954
- width: 24px;
955
- height: 24px;
956
- min-width: 24px;
957
- display: flex;
958
- align-items: center;
959
- justify-content: center;
960
- flex-shrink: 0;
1434
+ border-radius: 6px;
961
1435
  transition: background 0.15s;
962
1436
  }
963
1437
 
964
- .pp-reply-cancel:hover {
965
- background: ${isDark ? "rgba(255,255,255,0.2)" : "rgba(0,0,0,0.1)"};
1438
+ .pp-country-option:hover {
1439
+ background: ${colors.bgSecondary};
966
1440
  }
967
1441
 
968
- .pp-reply-cancel svg {
969
- width: 14px;
970
- height: 14px;
1442
+ .pp-country-option.selected {
1443
+ background: ${primaryColor}15;
971
1444
  }
972
1445
 
973
- /* Reply Quote in Message */
974
- .pp-reply-quote {
975
- background: ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"};
976
- border-left: 2px solid ${primaryColor};
977
- padding: 4px 8px;
978
- margin-bottom: 6px;
979
- border-radius: 0 4px 4px 0;
980
- font-size: 12px;
981
- position: relative;
982
- z-index: 1;
1446
+ .pp-country-name {
1447
+ flex: 1;
1448
+ font-size: 13px;
1449
+ color: ${colors.text};
983
1450
  }
984
1451
 
985
- .pp-reply-sender {
986
- display: block;
987
- font-weight: 500;
988
- color: ${primaryColor};
989
- margin-bottom: 2px;
1452
+ .pp-country-dial {
1453
+ font-size: 12px;
1454
+ color: ${colors.textSecondary};
990
1455
  }
991
1456
 
992
- .pp-reply-content {
993
- display: block;
994
- color: ${colors.textSecondary};
995
- white-space: nowrap;
996
- overflow: hidden;
997
- text-overflow: ellipsis;
1457
+ .pp-phone-number-input {
1458
+ flex: 1;
998
1459
  }
999
1460
 
1000
- /* Clickable reply quote */
1001
- .pp-reply-quote-clickable {
1461
+ .pp-prechat-submit {
1462
+ width: 100%;
1463
+ height: 48px;
1464
+ margin-top: 12px;
1465
+ border: none;
1466
+ border-radius: 8px;
1467
+ background: #00a884;
1468
+ color: white;
1469
+ font-size: 15px;
1470
+ font-weight: 500;
1002
1471
  cursor: pointer;
1003
- transition: background 0.15s, transform 0.1s;
1472
+ transition: background 0.2s, transform 0.1s;
1004
1473
  }
1005
1474
 
1006
- .pp-reply-quote-clickable:hover {
1007
- background: ${isDark ? "rgba(255,255,255,0.15)" : "rgba(0,0,0,0.08)"};
1475
+ .pp-prechat-submit:hover:not(:disabled) {
1476
+ background: #008f72;
1008
1477
  }
1009
1478
 
1010
- .pp-reply-quote-clickable:active {
1479
+ .pp-prechat-submit:active:not(:disabled) {
1011
1480
  transform: scale(0.98);
1012
1481
  }
1013
1482
 
1014
- /* Reply quote in visitor message bubble needs higher contrast */
1015
- .pp-message-visitor .pp-reply-quote {
1016
- background: rgba(255, 255, 255, 0.18);
1017
- border-left-color: rgba(255, 255, 255, 0.7);
1018
- }
1019
-
1020
- .pp-message-visitor .pp-reply-quote-clickable:hover {
1021
- background: rgba(255, 255, 255, 0.25);
1483
+ .pp-prechat-submit:disabled {
1484
+ background: ${isDark ? "#3b4a54" : "#b3b3b3"};
1485
+ cursor: not-allowed;
1022
1486
  }
1023
1487
 
1024
- .pp-message-visitor .pp-reply-sender,
1025
- .pp-message-visitor .pp-reply-content {
1026
- color: rgba(255, 255, 255, 0.9);
1488
+ .pp-prechat-skip {
1489
+ width: 100%;
1490
+ padding: 14px;
1491
+ margin-top: 8px;
1492
+ border: none;
1493
+ background: transparent;
1494
+ color: ${isDark ? "#8696a0" : "#667781"};
1495
+ font-size: 14px;
1496
+ cursor: pointer;
1497
+ transition: color 0.2s;
1027
1498
  }
1028
1499
 
1029
- /* Message highlight animation (when scrolling to a message) */
1030
- .pp-message-highlight {
1031
- animation: pp-highlight-pulse 1.5s ease-out;
1500
+ .pp-prechat-skip:hover {
1501
+ color: ${isDark ? "#aebac1" : "#3b4a54"};
1032
1502
  }
1503
+ `;
1504
+ }
1033
1505
 
1034
- @keyframes pp-highlight-pulse {
1035
- 0% {
1036
- box-shadow: 0 0 0 0 ${primaryColor}80;
1037
- }
1038
- 30% {
1039
- box-shadow: 0 0 0 6px ${primaryColor}40;
1506
+ // src/components/PreChatForm.tsx
1507
+ import { useState, useRef, useEffect } from "preact/hooks";
1508
+ import { parsePhoneNumber, isValidPhoneNumber } from "libphonenumber-js/min";
1509
+
1510
+ // src/data/countries.ts
1511
+ var countries = [
1512
+ // Europe
1513
+ { code: "FR", name: "France", dialCode: "+33", flag: "\u{1F1EB}\u{1F1F7}" },
1514
+ { code: "DE", name: "Germany", dialCode: "+49", flag: "\u{1F1E9}\u{1F1EA}" },
1515
+ { code: "GB", name: "United Kingdom", dialCode: "+44", flag: "\u{1F1EC}\u{1F1E7}" },
1516
+ { code: "ES", name: "Spain", dialCode: "+34", flag: "\u{1F1EA}\u{1F1F8}" },
1517
+ { code: "IT", name: "Italy", dialCode: "+39", flag: "\u{1F1EE}\u{1F1F9}" },
1518
+ { code: "PT", name: "Portugal", dialCode: "+351", flag: "\u{1F1F5}\u{1F1F9}" },
1519
+ { code: "NL", name: "Netherlands", dialCode: "+31", flag: "\u{1F1F3}\u{1F1F1}" },
1520
+ { code: "BE", name: "Belgium", dialCode: "+32", flag: "\u{1F1E7}\u{1F1EA}" },
1521
+ { code: "CH", name: "Switzerland", dialCode: "+41", flag: "\u{1F1E8}\u{1F1ED}" },
1522
+ { code: "AT", name: "Austria", dialCode: "+43", flag: "\u{1F1E6}\u{1F1F9}" },
1523
+ { code: "SE", name: "Sweden", dialCode: "+46", flag: "\u{1F1F8}\u{1F1EA}" },
1524
+ { code: "NO", name: "Norway", dialCode: "+47", flag: "\u{1F1F3}\u{1F1F4}" },
1525
+ { code: "DK", name: "Denmark", dialCode: "+45", flag: "\u{1F1E9}\u{1F1F0}" },
1526
+ { code: "FI", name: "Finland", dialCode: "+358", flag: "\u{1F1EB}\u{1F1EE}" },
1527
+ { code: "PL", name: "Poland", dialCode: "+48", flag: "\u{1F1F5}\u{1F1F1}" },
1528
+ { code: "CZ", name: "Czech Republic", dialCode: "+420", flag: "\u{1F1E8}\u{1F1FF}" },
1529
+ { code: "GR", name: "Greece", dialCode: "+30", flag: "\u{1F1EC}\u{1F1F7}" },
1530
+ { code: "IE", name: "Ireland", dialCode: "+353", flag: "\u{1F1EE}\u{1F1EA}" },
1531
+ { code: "RO", name: "Romania", dialCode: "+40", flag: "\u{1F1F7}\u{1F1F4}" },
1532
+ { code: "HU", name: "Hungary", dialCode: "+36", flag: "\u{1F1ED}\u{1F1FA}" },
1533
+ // North America
1534
+ { code: "US", name: "United States", dialCode: "+1", flag: "\u{1F1FA}\u{1F1F8}" },
1535
+ { code: "CA", name: "Canada", dialCode: "+1", flag: "\u{1F1E8}\u{1F1E6}" },
1536
+ { code: "MX", name: "Mexico", dialCode: "+52", flag: "\u{1F1F2}\u{1F1FD}" },
1537
+ // South America
1538
+ { code: "BR", name: "Brazil", dialCode: "+55", flag: "\u{1F1E7}\u{1F1F7}" },
1539
+ { code: "AR", name: "Argentina", dialCode: "+54", flag: "\u{1F1E6}\u{1F1F7}" },
1540
+ { code: "CL", name: "Chile", dialCode: "+56", flag: "\u{1F1E8}\u{1F1F1}" },
1541
+ { code: "CO", name: "Colombia", dialCode: "+57", flag: "\u{1F1E8}\u{1F1F4}" },
1542
+ { code: "PE", name: "Peru", dialCode: "+51", flag: "\u{1F1F5}\u{1F1EA}" },
1543
+ // Asia
1544
+ { code: "CN", name: "China", dialCode: "+86", flag: "\u{1F1E8}\u{1F1F3}" },
1545
+ { code: "JP", name: "Japan", dialCode: "+81", flag: "\u{1F1EF}\u{1F1F5}" },
1546
+ { code: "KR", name: "South Korea", dialCode: "+82", flag: "\u{1F1F0}\u{1F1F7}" },
1547
+ { code: "IN", name: "India", dialCode: "+91", flag: "\u{1F1EE}\u{1F1F3}" },
1548
+ { code: "ID", name: "Indonesia", dialCode: "+62", flag: "\u{1F1EE}\u{1F1E9}" },
1549
+ { code: "TH", name: "Thailand", dialCode: "+66", flag: "\u{1F1F9}\u{1F1ED}" },
1550
+ { code: "VN", name: "Vietnam", dialCode: "+84", flag: "\u{1F1FB}\u{1F1F3}" },
1551
+ { code: "MY", name: "Malaysia", dialCode: "+60", flag: "\u{1F1F2}\u{1F1FE}" },
1552
+ { code: "SG", name: "Singapore", dialCode: "+65", flag: "\u{1F1F8}\u{1F1EC}" },
1553
+ { code: "PH", name: "Philippines", dialCode: "+63", flag: "\u{1F1F5}\u{1F1ED}" },
1554
+ { code: "PK", name: "Pakistan", dialCode: "+92", flag: "\u{1F1F5}\u{1F1F0}" },
1555
+ { code: "BD", name: "Bangladesh", dialCode: "+880", flag: "\u{1F1E7}\u{1F1E9}" },
1556
+ // Middle East
1557
+ { code: "AE", name: "United Arab Emirates", dialCode: "+971", flag: "\u{1F1E6}\u{1F1EA}" },
1558
+ { code: "SA", name: "Saudi Arabia", dialCode: "+966", flag: "\u{1F1F8}\u{1F1E6}" },
1559
+ { code: "IL", name: "Israel", dialCode: "+972", flag: "\u{1F1EE}\u{1F1F1}" },
1560
+ { code: "TR", name: "Turkey", dialCode: "+90", flag: "\u{1F1F9}\u{1F1F7}" },
1561
+ { code: "EG", name: "Egypt", dialCode: "+20", flag: "\u{1F1EA}\u{1F1EC}" },
1562
+ // Africa
1563
+ { code: "ZA", name: "South Africa", dialCode: "+27", flag: "\u{1F1FF}\u{1F1E6}" },
1564
+ { code: "NG", name: "Nigeria", dialCode: "+234", flag: "\u{1F1F3}\u{1F1EC}" },
1565
+ { code: "KE", name: "Kenya", dialCode: "+254", flag: "\u{1F1F0}\u{1F1EA}" },
1566
+ { code: "MA", name: "Morocco", dialCode: "+212", flag: "\u{1F1F2}\u{1F1E6}" },
1567
+ { code: "TN", name: "Tunisia", dialCode: "+216", flag: "\u{1F1F9}\u{1F1F3}" },
1568
+ { code: "DZ", name: "Algeria", dialCode: "+213", flag: "\u{1F1E9}\u{1F1FF}" },
1569
+ // Oceania
1570
+ { code: "AU", name: "Australia", dialCode: "+61", flag: "\u{1F1E6}\u{1F1FA}" },
1571
+ { code: "NZ", name: "New Zealand", dialCode: "+64", flag: "\u{1F1F3}\u{1F1FF}" },
1572
+ // Russia & CIS
1573
+ { code: "RU", name: "Russia", dialCode: "+7", flag: "\u{1F1F7}\u{1F1FA}" },
1574
+ { code: "UA", name: "Ukraine", dialCode: "+380", flag: "\u{1F1FA}\u{1F1E6}" }
1575
+ ].sort((a, b) => a.name.localeCompare(b.name));
1576
+ function findCountryByCode(code) {
1577
+ return countries.find((c) => c.code === code.toUpperCase());
1578
+ }
1579
+ var defaultCountry = findCountryByCode("FR");
1580
+
1581
+ // src/components/PreChatForm.tsx
1582
+ import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
1583
+ var EmailIcon = () => /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1584
+ /* @__PURE__ */ jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" }),
1585
+ /* @__PURE__ */ jsx("path", { d: "M22 7l-10 7L2 7" })
1586
+ ] });
1587
+ var PhoneIcon = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-6-6 19.79 19.79 0 01-3.07-8.67A2 2 0 014.11 2h3a2 2 0 012 1.72 12.84 12.84 0 00.7 2.81 2 2 0 01-.45 2.11L8.09 9.91a16 16 0 006 6l1.27-1.27a2 2 0 012.11-.45 12.84 12.84 0 002.81.7A2 2 0 0122 16.92z" }) });
1588
+ var ChevronIcon = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "M6 9l6 6 6-6" }) });
1589
+ function isValidEmail(email) {
1590
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
1591
+ }
1592
+ function PreChatForm({ client: client2, config, onComplete, onSkip }) {
1593
+ const showEmailOnly = config.fields === "email-only";
1594
+ const showPhoneOnly = config.fields === "phone-only";
1595
+ const showBoth = config.fields === "email-and-phone";
1596
+ const showChoice = config.fields === "email-or-phone";
1597
+ const getDefaultTab = () => {
1598
+ if (showPhoneOnly) return "phone";
1599
+ return "email";
1600
+ };
1601
+ const [activeTab, setActiveTab] = useState(getDefaultTab());
1602
+ const [email, setEmail] = useState("");
1603
+ const [phone, setPhone] = useState("");
1604
+ const [selectedCountry, setSelectedCountry] = useState(defaultCountry);
1605
+ const [isCountryDropdownOpen, setIsCountryDropdownOpen] = useState(false);
1606
+ const [countrySearch, setCountrySearch] = useState("");
1607
+ const [emailError, setEmailError] = useState("");
1608
+ const [phoneError, setPhoneError] = useState("");
1609
+ const [isSubmitting, setIsSubmitting] = useState(false);
1610
+ const countryDropdownRef = useRef(null);
1611
+ const searchInputRef = useRef(null);
1612
+ useEffect(() => {
1613
+ const handleClickOutside = (e) => {
1614
+ if (countryDropdownRef.current && !countryDropdownRef.current.contains(e.target)) {
1615
+ setIsCountryDropdownOpen(false);
1040
1616
  }
1041
- 100% {
1042
- box-shadow: 0 0 0 0 ${primaryColor}00;
1617
+ };
1618
+ document.addEventListener("mousedown", handleClickOutside);
1619
+ return () => document.removeEventListener("mousedown", handleClickOutside);
1620
+ }, []);
1621
+ useEffect(() => {
1622
+ if (isCountryDropdownOpen && searchInputRef.current) {
1623
+ searchInputRef.current.focus();
1624
+ }
1625
+ }, [isCountryDropdownOpen]);
1626
+ const filteredCountries = countries.filter(
1627
+ (c) => c.name.toLowerCase().includes(countrySearch.toLowerCase()) || c.dialCode.includes(countrySearch) || c.code.toLowerCase().includes(countrySearch.toLowerCase())
1628
+ );
1629
+ const handleCountrySelect = (country) => {
1630
+ setSelectedCountry(country);
1631
+ setIsCountryDropdownOpen(false);
1632
+ setCountrySearch("");
1633
+ };
1634
+ const formatPhoneForDisplay = (value) => {
1635
+ const digits = value.replace(/\D/g, "");
1636
+ return digits;
1637
+ };
1638
+ const handlePhoneChange = (e) => {
1639
+ const target = e.target;
1640
+ const formatted = formatPhoneForDisplay(target.value);
1641
+ setPhone(formatted);
1642
+ setPhoneError("");
1643
+ };
1644
+ const getFullPhoneNumber = () => {
1645
+ if (!phone) return "";
1646
+ return `${selectedCountry.dialCode}${phone}`;
1647
+ };
1648
+ const validateForm = () => {
1649
+ let valid = true;
1650
+ if (showEmailOnly || showBoth) {
1651
+ if (!email.trim()) {
1652
+ setEmailError("Email is required");
1653
+ valid = false;
1654
+ } else if (!isValidEmail(email)) {
1655
+ setEmailError("Please enter a valid email");
1656
+ valid = false;
1043
1657
  }
1044
1658
  }
1045
-
1046
- /* Deleted Message */
1047
- .pp-message-deleted {
1048
- opacity: 0.6;
1049
- }
1050
-
1051
- .pp-deleted-content {
1052
- font-style: italic;
1053
- color: ${colors.textSecondary};
1054
- display: flex;
1055
- align-items: center;
1056
- gap: 4px;
1659
+ if (showPhoneOnly || showBoth) {
1660
+ const fullPhone = getFullPhoneNumber();
1661
+ if (!phone.trim()) {
1662
+ setPhoneError("Phone number is required");
1663
+ valid = false;
1664
+ } else if (!isValidPhoneNumber(fullPhone, selectedCountry.code)) {
1665
+ setPhoneError("Please enter a valid phone number");
1666
+ valid = false;
1667
+ }
1057
1668
  }
1058
-
1059
- .pp-deleted-icon {
1060
- font-size: 12px;
1669
+ if (showChoice) {
1670
+ if (activeTab === "email") {
1671
+ if (!email.trim()) {
1672
+ setEmailError("Email is required");
1673
+ valid = false;
1674
+ } else if (!isValidEmail(email)) {
1675
+ setEmailError("Please enter a valid email");
1676
+ valid = false;
1677
+ }
1678
+ } else {
1679
+ const fullPhone = getFullPhoneNumber();
1680
+ if (!phone.trim()) {
1681
+ setPhoneError("Phone number is required");
1682
+ valid = false;
1683
+ } else if (!isValidPhoneNumber(fullPhone, selectedCountry.code)) {
1684
+ setPhoneError("Please enter a valid phone number");
1685
+ valid = false;
1686
+ }
1687
+ }
1061
1688
  }
1062
-
1063
- /* Edited Badge */
1064
- .pp-edited-badge {
1065
- font-size: 10px;
1066
- color: ${colors.textSecondary};
1067
- margin-left: 4px;
1068
- font-style: italic;
1689
+ return valid;
1690
+ };
1691
+ const handleSubmit = async (e) => {
1692
+ e.preventDefault();
1693
+ if (!validateForm()) return;
1694
+ setIsSubmitting(true);
1695
+ try {
1696
+ const data = {};
1697
+ if (showEmailOnly || showBoth || showChoice && activeTab === "email") {
1698
+ data.email = email.trim();
1699
+ }
1700
+ if (showPhoneOnly || showBoth || showChoice && activeTab === "phone") {
1701
+ const fullPhone = getFullPhoneNumber();
1702
+ const parsed = parsePhoneNumber(fullPhone, selectedCountry.code);
1703
+ if (parsed) {
1704
+ data.phone = parsed.format("E.164");
1705
+ data.phoneCountry = selectedCountry.code;
1706
+ }
1707
+ }
1708
+ await client2.submitPreChat(data);
1709
+ onComplete();
1710
+ } catch (err) {
1711
+ console.error("[PreChatForm] Submit error:", err);
1712
+ if (activeTab === "email" || showEmailOnly || showBoth) {
1713
+ setEmailError("Something went wrong. Please try again.");
1714
+ } else {
1715
+ setPhoneError("Something went wrong. Please try again.");
1716
+ }
1717
+ } finally {
1718
+ setIsSubmitting(false);
1069
1719
  }
1070
- `;
1720
+ };
1721
+ const renderEmailField = () => /* @__PURE__ */ jsxs("div", { class: "pp-prechat-field", children: [
1722
+ /* @__PURE__ */ jsx("label", { class: "pp-prechat-label", children: "Email address" }),
1723
+ /* @__PURE__ */ jsx(
1724
+ "input",
1725
+ {
1726
+ type: "email",
1727
+ class: `pp-prechat-input ${emailError ? "error" : ""}`,
1728
+ placeholder: "you@example.com",
1729
+ value: email,
1730
+ onInput: (e) => {
1731
+ setEmail(e.target.value);
1732
+ setEmailError("");
1733
+ }
1734
+ }
1735
+ ),
1736
+ emailError && /* @__PURE__ */ jsx("div", { class: "pp-prechat-error", children: emailError })
1737
+ ] });
1738
+ const renderPhoneField = () => /* @__PURE__ */ jsxs("div", { class: "pp-prechat-field", children: [
1739
+ /* @__PURE__ */ jsx("label", { class: "pp-prechat-label", children: "Phone number" }),
1740
+ /* @__PURE__ */ jsxs("div", { class: "pp-phone-input-wrapper", children: [
1741
+ /* @__PURE__ */ jsxs("div", { class: "pp-country-select", ref: countryDropdownRef, children: [
1742
+ /* @__PURE__ */ jsxs(
1743
+ "button",
1744
+ {
1745
+ type: "button",
1746
+ class: "pp-country-btn",
1747
+ onClick: () => setIsCountryDropdownOpen(!isCountryDropdownOpen),
1748
+ children: [
1749
+ /* @__PURE__ */ jsx("span", { class: "pp-country-flag", children: selectedCountry.flag }),
1750
+ /* @__PURE__ */ jsx("span", { class: "pp-country-code", children: selectedCountry.dialCode }),
1751
+ /* @__PURE__ */ jsx(ChevronIcon, {})
1752
+ ]
1753
+ }
1754
+ ),
1755
+ isCountryDropdownOpen && /* @__PURE__ */ jsxs("div", { class: "pp-country-dropdown", children: [
1756
+ /* @__PURE__ */ jsx("div", { class: "pp-country-search", children: /* @__PURE__ */ jsx(
1757
+ "input",
1758
+ {
1759
+ ref: searchInputRef,
1760
+ type: "text",
1761
+ class: "pp-country-search-input",
1762
+ placeholder: "Search country...",
1763
+ value: countrySearch,
1764
+ onInput: (e) => setCountrySearch(e.target.value)
1765
+ }
1766
+ ) }),
1767
+ /* @__PURE__ */ jsx("div", { class: "pp-country-list", children: filteredCountries.map((country) => /* @__PURE__ */ jsxs(
1768
+ "div",
1769
+ {
1770
+ class: `pp-country-option ${country.code === selectedCountry.code ? "selected" : ""}`,
1771
+ onClick: () => handleCountrySelect(country),
1772
+ children: [
1773
+ /* @__PURE__ */ jsx("span", { class: "pp-country-flag", children: country.flag }),
1774
+ /* @__PURE__ */ jsx("span", { class: "pp-country-name", children: country.name }),
1775
+ /* @__PURE__ */ jsx("span", { class: "pp-country-dial", children: country.dialCode })
1776
+ ]
1777
+ },
1778
+ country.code
1779
+ )) })
1780
+ ] })
1781
+ ] }),
1782
+ /* @__PURE__ */ jsx(
1783
+ "input",
1784
+ {
1785
+ type: "tel",
1786
+ class: `pp-prechat-input pp-phone-number-input ${phoneError ? "error" : ""}`,
1787
+ placeholder: "612 345 678",
1788
+ value: phone,
1789
+ onInput: handlePhoneChange
1790
+ }
1791
+ )
1792
+ ] }),
1793
+ phoneError && /* @__PURE__ */ jsx("div", { class: "pp-prechat-error", children: phoneError })
1794
+ ] });
1795
+ return /* @__PURE__ */ jsxs("div", { class: "pp-prechat", children: [
1796
+ /* @__PURE__ */ jsx("h2", { class: "pp-prechat-title", children: "How can we reach you?" }),
1797
+ /* @__PURE__ */ jsx("p", { class: "pp-prechat-subtitle", children: showBoth ? "Please provide your contact information so we can follow up if needed." : showChoice ? "Choose how you would like us to contact you." : showEmailOnly ? "Enter your email so we can follow up with you." : "Enter your phone number so we can call you back." }),
1798
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
1799
+ showChoice && /* @__PURE__ */ jsxs("div", { class: "pp-prechat-tabs", children: [
1800
+ /* @__PURE__ */ jsxs(
1801
+ "button",
1802
+ {
1803
+ type: "button",
1804
+ class: `pp-prechat-tab ${activeTab === "email" ? "active" : ""}`,
1805
+ onClick: () => {
1806
+ setActiveTab("email");
1807
+ setPhoneError("");
1808
+ },
1809
+ children: [
1810
+ /* @__PURE__ */ jsx(EmailIcon, {}),
1811
+ "Email"
1812
+ ]
1813
+ }
1814
+ ),
1815
+ /* @__PURE__ */ jsxs(
1816
+ "button",
1817
+ {
1818
+ type: "button",
1819
+ class: `pp-prechat-tab ${activeTab === "phone" ? "active" : ""}`,
1820
+ onClick: () => {
1821
+ setActiveTab("phone");
1822
+ setEmailError("");
1823
+ },
1824
+ children: [
1825
+ /* @__PURE__ */ jsx(PhoneIcon, {}),
1826
+ "Phone"
1827
+ ]
1828
+ }
1829
+ )
1830
+ ] }),
1831
+ showEmailOnly && renderEmailField(),
1832
+ showPhoneOnly && renderPhoneField(),
1833
+ showBoth && /* @__PURE__ */ jsxs(Fragment, { children: [
1834
+ renderEmailField(),
1835
+ renderPhoneField()
1836
+ ] }),
1837
+ showChoice && /* @__PURE__ */ jsxs(Fragment, { children: [
1838
+ activeTab === "email" && renderEmailField(),
1839
+ activeTab === "phone" && renderPhoneField()
1840
+ ] }),
1841
+ /* @__PURE__ */ jsx("button", { type: "submit", class: "pp-prechat-submit", disabled: isSubmitting, children: isSubmitting ? "Submitting..." : "Start chatting" }),
1842
+ !config.required && /* @__PURE__ */ jsx("button", { type: "button", class: "pp-prechat-skip", onClick: onSkip, children: "Skip for now" })
1843
+ ] })
1844
+ ] });
1071
1845
  }
1072
1846
 
1073
1847
  // src/components/ChatWidget.tsx
1074
- import { Fragment as Fragment2, jsx, jsxs } from "preact/jsx-runtime";
1848
+ import { Fragment as Fragment3, jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
1075
1849
  function formatDateSeparator(date) {
1076
1850
  const now = /* @__PURE__ */ new Date();
1077
1851
  const messageDate = new Date(date);
@@ -1091,28 +1865,31 @@ function getDateKey(date) {
1091
1865
  return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
1092
1866
  }
1093
1867
  function ChatWidget({ client: client2, config: initialConfig }) {
1094
- const [isOpen, setIsOpen] = useState(false);
1095
- const [messages, setMessages] = useState([]);
1096
- const [inputValue, setInputValue] = useState("");
1097
- const [isTyping, setIsTyping] = useState(false);
1098
- const [operatorOnline, setOperatorOnline] = useState(false);
1099
- const [isConnected, setIsConnected] = useState(false);
1100
- const [unreadCount, setUnreadCount] = useState(0);
1101
- const [pendingAttachments, setPendingAttachments] = useState([]);
1102
- const [isUploading, setIsUploading] = useState(false);
1103
- const [replyingTo, setReplyingTo] = useState(null);
1104
- const [editingMessage, setEditingMessage] = useState(null);
1105
- const [editContent, setEditContent] = useState("");
1106
- const [messageMenu, setMessageMenu] = useState(null);
1107
- const [isDragging, setIsDragging] = useState(false);
1108
- const [hoveredMessageId, setHoveredMessageId] = useState(null);
1109
- const [longPressTimer, setLongPressTimer] = useState(null);
1110
- const [config, setConfig] = useState(initialConfig);
1111
- const messagesEndRef = useRef(null);
1112
- const inputRef = useRef(null);
1113
- const fileInputRef = useRef(null);
1114
- const messagesContainerRef = useRef(null);
1115
- useEffect(() => {
1868
+ const [isOpen, setIsOpen] = useState2(false);
1869
+ const [messages, setMessages] = useState2([]);
1870
+ const [inputValue, setInputValue] = useState2("");
1871
+ const [isTyping, setIsTyping] = useState2(false);
1872
+ const [operatorOnline, setOperatorOnline] = useState2(false);
1873
+ const [isConnected, setIsConnected] = useState2(false);
1874
+ const [unreadCount, setUnreadCount] = useState2(0);
1875
+ const [pendingAttachments, setPendingAttachments] = useState2([]);
1876
+ const [isUploading, setIsUploading] = useState2(false);
1877
+ const [replyingTo, setReplyingTo] = useState2(null);
1878
+ const [editingMessage, setEditingMessage] = useState2(null);
1879
+ const [editContent, setEditContent] = useState2("");
1880
+ const [messageMenu, setMessageMenu] = useState2(null);
1881
+ const [isDragging, setIsDragging] = useState2(false);
1882
+ const [swipedMessageId, setSwipedMessageId] = useState2(null);
1883
+ const [swipeOffset, setSwipeOffset] = useState2(0);
1884
+ const touchStartRef = useRef2(null);
1885
+ const [config, setConfig] = useState2(initialConfig);
1886
+ const [preChatForm, setPreChatForm] = useState2(void 0);
1887
+ const [preChatSkipped, setPreChatSkipped] = useState2(false);
1888
+ const messagesEndRef = useRef2(null);
1889
+ const inputRef = useRef2(null);
1890
+ const fileInputRef = useRef2(null);
1891
+ const messagesContainerRef = useRef2(null);
1892
+ useEffect2(() => {
1116
1893
  const unsubOpen = client2.on("openChange", setIsOpen);
1117
1894
  const unsubMessage = client2.on("message", () => {
1118
1895
  setMessages([...client2.getMessages()]);
@@ -1128,6 +1905,10 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1128
1905
  setMessages(client2.getMessages());
1129
1906
  setOperatorOnline(client2.getSession()?.operatorOnline ?? false);
1130
1907
  setConfig(client2.getConfig());
1908
+ setPreChatForm(client2.getSession()?.preChatForm);
1909
+ });
1910
+ const unsubPreChat = client2.on("preChatCompleted", () => {
1911
+ setPreChatForm((prev) => prev ? { ...prev, completed: true } : prev);
1131
1912
  });
1132
1913
  const unsubConfig = client2.on("configUpdate", () => {
1133
1914
  setConfig(client2.getConfig());
@@ -1137,6 +1918,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1137
1918
  setMessages(client2.getMessages());
1138
1919
  setOperatorOnline(client2.getSession()?.operatorOnline ?? false);
1139
1920
  setConfig(client2.getConfig());
1921
+ setPreChatForm(client2.getSession()?.preChatForm);
1140
1922
  }
1141
1923
  return () => {
1142
1924
  unsubOpen();
@@ -1144,15 +1926,16 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1144
1926
  unsubTyping();
1145
1927
  unsubPresence();
1146
1928
  unsubConnect();
1929
+ unsubPreChat();
1147
1930
  unsubConfig();
1148
1931
  };
1149
1932
  }, [client2]);
1150
- useEffect(() => {
1933
+ useEffect2(() => {
1151
1934
  if (isOpen) {
1152
1935
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
1153
1936
  }
1154
1937
  }, [messages, isOpen]);
1155
- useEffect(() => {
1938
+ useEffect2(() => {
1156
1939
  if (isOpen) {
1157
1940
  setTimeout(() => {
1158
1941
  messagesEndRef.current?.scrollIntoView({ behavior: "auto" });
@@ -1161,7 +1944,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1161
1944
  setUnreadCount(0);
1162
1945
  }
1163
1946
  }, [isOpen]);
1164
- useEffect(() => {
1947
+ useEffect2(() => {
1165
1948
  if (!isOpen && messages.length > 0) {
1166
1949
  const unread = messages.filter(
1167
1950
  (msg) => msg.sender !== "visitor" && msg.status !== "read"
@@ -1179,14 +1962,14 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1179
1962
  client2.sendReadStatus(messageIds, "read");
1180
1963
  }
1181
1964
  }, [isOpen, isConnected, messages, client2]);
1182
- useEffect(() => {
1965
+ useEffect2(() => {
1183
1966
  if (!isOpen || !isConnected) return;
1184
1967
  const timer = setTimeout(() => {
1185
1968
  markMessagesAsRead();
1186
1969
  }, 1e3);
1187
1970
  return () => clearTimeout(timer);
1188
1971
  }, [isOpen, isConnected, messages, markMessagesAsRead]);
1189
- useEffect(() => {
1972
+ useEffect2(() => {
1190
1973
  const handleVisibilityChange = () => {
1191
1974
  if (document.visibilityState === "visible" && isOpen) {
1192
1975
  markMessagesAsRead();
@@ -1195,7 +1978,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1195
1978
  document.addEventListener("visibilitychange", handleVisibilityChange);
1196
1979
  return () => document.removeEventListener("visibilitychange", handleVisibilityChange);
1197
1980
  }, [isOpen, markMessagesAsRead]);
1198
- useEffect(() => {
1981
+ useEffect2(() => {
1199
1982
  const unsubRead = client2.on(
1200
1983
  "read",
1201
1984
  () => {
@@ -1334,26 +2117,43 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1334
2117
  y: mouseEvent.clientY
1335
2118
  });
1336
2119
  };
1337
- const handleTouchStart = (message) => {
1338
- const timer = setTimeout(() => {
1339
- if (navigator.vibrate) navigator.vibrate(50);
1340
- setMessageMenu({
1341
- message,
1342
- x: window.innerWidth / 2 - 60,
1343
- // Center horizontally
1344
- y: window.innerHeight / 2 - 50
1345
- // Center vertically
1346
- });
1347
- }, 500);
1348
- setLongPressTimer(timer);
2120
+ const handleTouchStart = (e, message) => {
2121
+ const touch = e.touches[0];
2122
+ touchStartRef.current = { x: touch.clientX, y: touch.clientY, time: Date.now() };
2123
+ if (swipedMessageId && swipedMessageId !== message.id) {
2124
+ setSwipedMessageId(null);
2125
+ setSwipeOffset(0);
2126
+ }
1349
2127
  };
1350
- const handleTouchEnd = () => {
1351
- if (longPressTimer) {
1352
- clearTimeout(longPressTimer);
1353
- setLongPressTimer(null);
2128
+ const handleTouchMove = (e, message) => {
2129
+ if (!touchStartRef.current) return;
2130
+ const touch = e.touches[0];
2131
+ const deltaX = touch.clientX - touchStartRef.current.x;
2132
+ const deltaY = touch.clientY - touchStartRef.current.y;
2133
+ if (Math.abs(deltaY) > Math.abs(deltaX)) return;
2134
+ if (deltaX < 0) {
2135
+ const offset = Math.max(deltaX, -100);
2136
+ setSwipeOffset(offset);
2137
+ setSwipedMessageId(message.id);
1354
2138
  }
1355
2139
  };
1356
- useEffect(() => {
2140
+ const handleTouchEnd = (message) => {
2141
+ if (!touchStartRef.current) return;
2142
+ const elapsed = Date.now() - touchStartRef.current.time;
2143
+ if (swipeOffset < -50 || swipeOffset < -20 && elapsed < 200) {
2144
+ setSwipeOffset(-80);
2145
+ if (navigator.vibrate) navigator.vibrate(30);
2146
+ } else {
2147
+ setSwipeOffset(0);
2148
+ setSwipedMessageId(null);
2149
+ }
2150
+ touchStartRef.current = null;
2151
+ };
2152
+ const resetSwipe = () => {
2153
+ setSwipedMessageId(null);
2154
+ setSwipeOffset(0);
2155
+ };
2156
+ useEffect2(() => {
1357
2157
  if (!messageMenu) return;
1358
2158
  const handleClickOutside = () => setMessageMenu(null);
1359
2159
  document.addEventListener("click", handleClickOutside);
@@ -1369,7 +2169,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1369
2169
  }, 1500);
1370
2170
  }
1371
2171
  };
1372
- const dragCounterRef = useRef(0);
2172
+ const dragCounterRef = useRef2(0);
1373
2173
  const handleDragEnter = (e) => {
1374
2174
  e.preventDefault();
1375
2175
  e.stopPropagation();
@@ -1445,22 +2245,32 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1445
2245
  const theme = getTheme(config.theme ?? "auto");
1446
2246
  const primaryColor = config.primaryColor ?? "#6366f1";
1447
2247
  const actionIconColor = theme === "dark" ? "#9ca3af" : "#6b7280";
1448
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1449
- /* @__PURE__ */ jsx("style", { children: styles(primaryColor, theme) }),
1450
- /* @__PURE__ */ jsxs(
2248
+ const styleOptions = {
2249
+ primaryColor,
2250
+ theme,
2251
+ headerColor: config.headerColor,
2252
+ footerColor: config.footerColor,
2253
+ chatBackground: config.chatBackground,
2254
+ toggleColor: config.toggleColor
2255
+ };
2256
+ const shouldShowPreChat = preChatForm && preChatForm.enabled && !preChatForm.completed && !preChatSkipped && // Before first message: show immediately
2257
+ (preChatForm.timing === "before-first-message" && messages.length === 0 || preChatForm.timing === "after-first-message" && messages.some((m) => m.sender === "visitor"));
2258
+ return /* @__PURE__ */ jsxs2(Fragment2, { children: [
2259
+ /* @__PURE__ */ jsx2("style", { children: styles(styleOptions) }),
2260
+ !isOpen && /* @__PURE__ */ jsxs2(
1451
2261
  "button",
1452
2262
  {
1453
2263
  class: `pp-toggle pp-${position}`,
1454
2264
  onClick: () => client2.toggleOpen(),
1455
- "aria-label": isOpen ? "Close chat" : "Open chat",
2265
+ "aria-label": "Open chat",
1456
2266
  children: [
1457
- isOpen ? /* @__PURE__ */ jsx(CloseIcon, {}) : /* @__PURE__ */ jsx(ChatIcon, {}),
1458
- !isOpen && unreadCount > 0 && /* @__PURE__ */ jsx("span", { class: "pp-unread-badge", children: unreadCount > 9 ? "9+" : unreadCount }),
1459
- !isOpen && unreadCount === 0 && operatorOnline && /* @__PURE__ */ jsx("span", { class: "pp-online-dot" })
2267
+ /* @__PURE__ */ jsx2(ChatIcon, {}),
2268
+ unreadCount > 0 && /* @__PURE__ */ jsx2("span", { class: "pp-unread-badge", children: unreadCount > 9 ? "9+" : unreadCount }),
2269
+ unreadCount === 0 && operatorOnline && /* @__PURE__ */ jsx2("span", { class: "pp-online-dot" })
1460
2270
  ]
1461
2271
  }
1462
2272
  ),
1463
- isOpen && /* @__PURE__ */ jsxs(
2273
+ isOpen && /* @__PURE__ */ jsxs2(
1464
2274
  "div",
1465
2275
  {
1466
2276
  class: `pp-window pp-${position} pp-theme-${theme} ${isDragging ? "pp-dragging" : ""}`,
@@ -1469,36 +2279,49 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1469
2279
  onDragLeave: handleDragLeave,
1470
2280
  onDrop: handleDrop,
1471
2281
  children: [
1472
- isDragging && /* @__PURE__ */ jsxs("div", { class: "pp-drop-overlay", children: [
1473
- /* @__PURE__ */ jsx("div", { class: "pp-drop-icon", children: /* @__PURE__ */ jsx(AttachIcon, {}) }),
1474
- /* @__PURE__ */ jsx("div", { class: "pp-drop-text", children: "Drop files to upload" })
2282
+ isDragging && /* @__PURE__ */ jsxs2("div", { class: "pp-drop-overlay", children: [
2283
+ /* @__PURE__ */ jsx2("div", { class: "pp-drop-icon", children: /* @__PURE__ */ jsx2(AttachIcon, {}) }),
2284
+ /* @__PURE__ */ jsx2("div", { class: "pp-drop-text", children: "Drop files to upload" })
1475
2285
  ] }),
1476
- /* @__PURE__ */ jsxs("div", { class: "pp-header", children: [
1477
- /* @__PURE__ */ jsxs("div", { class: "pp-header-info", children: [
1478
- config.operatorAvatar && /* @__PURE__ */ jsx("img", { src: config.operatorAvatar, alt: "", class: "pp-avatar" }),
1479
- /* @__PURE__ */ jsxs("div", { children: [
1480
- /* @__PURE__ */ jsx("div", { class: "pp-header-title", children: config.operatorName ?? "Support" }),
1481
- /* @__PURE__ */ jsx("div", { class: "pp-header-status", children: operatorOnline ? /* @__PURE__ */ jsxs(Fragment2, { children: [
1482
- /* @__PURE__ */ jsx("span", { class: "pp-status-dot pp-online" }),
2286
+ /* @__PURE__ */ jsxs2("div", { class: "pp-header", children: [
2287
+ /* @__PURE__ */ jsxs2("div", { class: "pp-header-info", children: [
2288
+ config.operatorAvatar && /* @__PURE__ */ jsx2("img", { src: config.operatorAvatar, alt: "", class: "pp-avatar" }),
2289
+ /* @__PURE__ */ jsxs2("div", { children: [
2290
+ /* @__PURE__ */ jsx2("div", { class: "pp-header-title", children: config.operatorName ?? "Support" }),
2291
+ /* @__PURE__ */ jsx2("div", { class: "pp-header-status", children: operatorOnline ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
2292
+ /* @__PURE__ */ jsx2("span", { class: "pp-status-dot pp-online" }),
1483
2293
  " Online"
1484
- ] }) : /* @__PURE__ */ jsxs(Fragment2, { children: [
1485
- /* @__PURE__ */ jsx("span", { class: "pp-status-dot" }),
2294
+ ] }) : /* @__PURE__ */ jsxs2(Fragment3, { children: [
2295
+ /* @__PURE__ */ jsx2("span", { class: "pp-status-dot" }),
1486
2296
  " Away"
1487
2297
  ] }) })
1488
2298
  ] })
1489
2299
  ] }),
1490
- /* @__PURE__ */ jsx(
2300
+ /* @__PURE__ */ jsx2(
1491
2301
  "button",
1492
2302
  {
1493
2303
  class: "pp-close-btn",
1494
2304
  onClick: () => client2.setOpen(false),
1495
2305
  "aria-label": "Close chat",
1496
- children: /* @__PURE__ */ jsx(CloseIcon, {})
2306
+ children: /* @__PURE__ */ jsx2(CloseIcon, {})
1497
2307
  }
1498
2308
  )
1499
2309
  ] }),
1500
- /* @__PURE__ */ jsxs("div", { class: "pp-messages", ref: messagesContainerRef, children: [
1501
- config.welcomeMessage && messages.length === 0 && /* @__PURE__ */ jsx("div", { class: "pp-welcome", children: config.welcomeMessage }),
2310
+ shouldShowPreChat && preChatForm && /* @__PURE__ */ jsx2(
2311
+ PreChatForm,
2312
+ {
2313
+ client: client2,
2314
+ config: preChatForm,
2315
+ onComplete: () => {
2316
+ setPreChatForm((prev) => prev ? { ...prev, completed: true } : prev);
2317
+ },
2318
+ onSkip: () => {
2319
+ setPreChatSkipped(true);
2320
+ }
2321
+ }
2322
+ ),
2323
+ !shouldShowPreChat && /* @__PURE__ */ jsxs2("div", { class: "pp-messages", ref: messagesContainerRef, onClick: () => swipedMessageId && resetSwipe(), children: [
2324
+ config.welcomeMessage && messages.length === 0 && /* @__PURE__ */ jsx2("div", { class: "pp-welcome", children: config.welcomeMessage }),
1502
2325
  messages.map((msg, index) => {
1503
2326
  const isDeleted = !!msg.deletedAt;
1504
2327
  const isEdited = !!msg.editedAt;
@@ -1524,127 +2347,145 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1524
2347
  }
1525
2348
  }
1526
2349
  }
1527
- const isHovered = hoveredMessageId === msg.id;
1528
- const showActions = isHovered && !isDeleted;
1529
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1530
- showDateSeparator && /* @__PURE__ */ jsx("div", { class: "pp-date-separator", children: /* @__PURE__ */ jsx("span", { children: formatDateSeparator(msgDate) }) }),
1531
- /* @__PURE__ */ jsxs(
1532
- "div",
1533
- {
1534
- id: `pp-msg-${msg.id}`,
1535
- class: `pp-message pp-message-${msg.sender} ${isDeleted ? "pp-message-deleted" : ""}`,
1536
- onContextMenu: (e) => handleMessageContextMenu(e, msg),
1537
- onMouseEnter: () => setHoveredMessageId(msg.id),
1538
- onMouseLeave: () => setHoveredMessageId(null),
1539
- onTouchStart: () => handleTouchStart(msg),
1540
- onTouchEnd: handleTouchEnd,
1541
- onTouchCancel: handleTouchEnd,
1542
- children: [
1543
- showActions && /* @__PURE__ */ jsxs("div", { class: `pp-message-actions ${msg.sender === "visitor" ? "pp-actions-left" : "pp-actions-right"}`, children: [
1544
- /* @__PURE__ */ jsx(
1545
- "button",
2350
+ const isSwiped = swipedMessageId === msg.id;
2351
+ const msgSwipeOffset = isSwiped ? swipeOffset : 0;
2352
+ return /* @__PURE__ */ jsxs2(Fragment2, { children: [
2353
+ showDateSeparator && /* @__PURE__ */ jsx2("div", { class: "pp-date-separator", children: /* @__PURE__ */ jsx2("span", { children: formatDateSeparator(msgDate) }) }),
2354
+ /* @__PURE__ */ jsxs2("div", { class: `pp-message-swipe-container ${msg.sender === "visitor" ? "pp-swipe-left" : "pp-swipe-right"}`, children: [
2355
+ /* @__PURE__ */ jsxs2("div", { class: "pp-swipe-actions", children: [
2356
+ /* @__PURE__ */ jsx2(
2357
+ "button",
2358
+ {
2359
+ class: "pp-swipe-action pp-swipe-reply",
2360
+ onClick: () => {
2361
+ handleReply(msg);
2362
+ resetSwipe();
2363
+ },
2364
+ children: /* @__PURE__ */ jsx2(ReplyIcon, { color: "#fff" })
2365
+ }
2366
+ ),
2367
+ msg.sender === "visitor" && !isDeleted && /* @__PURE__ */ jsxs2(Fragment3, { children: [
2368
+ /* @__PURE__ */ jsx2(
2369
+ "button",
2370
+ {
2371
+ class: "pp-swipe-action pp-swipe-edit",
2372
+ onClick: () => {
2373
+ handleStartEdit(msg);
2374
+ resetSwipe();
2375
+ },
2376
+ children: /* @__PURE__ */ jsx2(EditIcon, { color: "#fff" })
2377
+ }
2378
+ ),
2379
+ /* @__PURE__ */ jsx2(
2380
+ "button",
2381
+ {
2382
+ class: "pp-swipe-action pp-swipe-delete",
2383
+ onClick: () => {
2384
+ handleDelete(msg);
2385
+ resetSwipe();
2386
+ },
2387
+ children: /* @__PURE__ */ jsx2(DeleteIcon, { color: "#fff" })
2388
+ }
2389
+ )
2390
+ ] })
2391
+ ] }),
2392
+ /* @__PURE__ */ jsxs2(
2393
+ "div",
2394
+ {
2395
+ id: `pp-msg-${msg.id}`,
2396
+ class: `pp-message pp-message-${msg.sender} ${isDeleted ? "pp-message-deleted" : ""}`,
2397
+ style: { transform: `translateX(${msgSwipeOffset}px)`, transition: touchStartRef.current ? "none" : "transform 0.2s ease-out" },
2398
+ onContextMenu: (e) => handleMessageContextMenu(e, msg),
2399
+ onTouchStart: (e) => handleTouchStart(e, msg),
2400
+ onTouchMove: (e) => handleTouchMove(e, msg),
2401
+ onTouchEnd: () => handleTouchEnd(msg),
2402
+ onTouchCancel: () => handleTouchEnd(msg),
2403
+ children: [
2404
+ replyData && (replyData.content || replyData.hasAttachment) && /* @__PURE__ */ jsxs2(
2405
+ "div",
1546
2406
  {
1547
- class: "pp-action-btn",
1548
- onClick: () => handleReply(msg),
1549
- title: "Reply",
1550
- children: /* @__PURE__ */ jsx(ReplyIcon, { color: actionIconColor })
2407
+ class: "pp-reply-quote pp-reply-quote-clickable",
2408
+ onClick: () => scrollToMessage(replyData.id),
2409
+ role: "button",
2410
+ tabIndex: 0,
2411
+ onKeyDown: (e) => e.key === "Enter" && scrollToMessage(replyData.id),
2412
+ children: [
2413
+ /* @__PURE__ */ jsx2("span", { class: "pp-reply-sender", children: replyData.sender === "visitor" ? "You" : "Support" }),
2414
+ /* @__PURE__ */ jsx2("span", { class: "pp-reply-content", children: replyData.deleted ? "Message deleted" : /* @__PURE__ */ jsxs2(Fragment3, { children: [
2415
+ replyData.hasAttachment && /* @__PURE__ */ jsx2("span", { class: "pp-reply-attachment-icon", children: replyData.attachmentType?.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
2416
+ replyData.content ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
2417
+ (replyData.content || "").slice(0, 50),
2418
+ (replyData.content || "").length > 50 ? "..." : ""
2419
+ ] }) : replyData.attachmentType?.startsWith("image/") ? "Photo" : "File"
2420
+ ] }) })
2421
+ ]
1551
2422
  }
1552
2423
  ),
1553
- msg.sender === "visitor" && /* @__PURE__ */ jsxs(Fragment2, { children: [
1554
- /* @__PURE__ */ jsx(
1555
- "button",
1556
- {
1557
- class: "pp-action-btn",
1558
- onClick: () => handleStartEdit(msg),
1559
- title: "Edit",
1560
- children: /* @__PURE__ */ jsx(EditIcon, { color: actionIconColor })
1561
- }
1562
- ),
1563
- /* @__PURE__ */ jsx(
1564
- "button",
1565
- {
1566
- class: "pp-action-btn pp-action-delete",
1567
- onClick: () => handleDelete(msg),
1568
- title: "Delete",
1569
- children: /* @__PURE__ */ jsx(DeleteIcon, { color: actionIconColor })
1570
- }
1571
- )
2424
+ isDeleted ? /* @__PURE__ */ jsxs2("div", { class: "pp-message-content pp-deleted-content", children: [
2425
+ /* @__PURE__ */ jsx2("span", { class: "pp-deleted-icon", children: "\u{1F5D1}\uFE0F" }),
2426
+ " Message deleted"
2427
+ ] }) : /* @__PURE__ */ jsxs2(Fragment3, { children: [
2428
+ msg.content && /* @__PURE__ */ jsxs2("div", { class: "pp-message-content", children: [
2429
+ msg.content,
2430
+ /* @__PURE__ */ jsxs2("span", { class: "pp-message-time", children: [
2431
+ formatTime(msg.timestamp),
2432
+ isEdited && /* @__PURE__ */ jsx2("span", { class: "pp-edited-badge", children: "edited" }),
2433
+ msg.sender === "ai" && /* @__PURE__ */ jsx2("span", { class: "pp-ai-badge", children: "AI" }),
2434
+ msg.sender === "visitor" && /* @__PURE__ */ jsx2("span", { class: `pp-status pp-status-${msg.status ?? "sent"}`, children: /* @__PURE__ */ jsx2(StatusIcon, { status: msg.status }) })
2435
+ ] })
2436
+ ] }),
2437
+ msg.attachments && msg.attachments.length > 0 && /* @__PURE__ */ jsxs2("div", { class: "pp-message-attachments", children: [
2438
+ msg.attachments.map((att) => /* @__PURE__ */ jsx2(AttachmentDisplay, { attachment: att }, att.id)),
2439
+ !msg.content && /* @__PURE__ */ jsxs2("span", { class: "pp-message-time pp-attachment-time", children: [
2440
+ formatTime(msg.timestamp),
2441
+ isEdited && /* @__PURE__ */ jsx2("span", { class: "pp-edited-badge", children: "edited" }),
2442
+ msg.sender === "ai" && /* @__PURE__ */ jsx2("span", { class: "pp-ai-badge", children: "AI" }),
2443
+ msg.sender === "visitor" && /* @__PURE__ */ jsx2("span", { class: `pp-status pp-status-${msg.status ?? "sent"}`, children: /* @__PURE__ */ jsx2(StatusIcon, { status: msg.status }) })
2444
+ ] })
2445
+ ] })
1572
2446
  ] })
1573
- ] }),
1574
- replyData && (replyData.content || replyData.hasAttachment) && /* @__PURE__ */ jsxs(
1575
- "div",
1576
- {
1577
- class: "pp-reply-quote pp-reply-quote-clickable",
1578
- onClick: () => scrollToMessage(replyData.id),
1579
- role: "button",
1580
- tabIndex: 0,
1581
- onKeyDown: (e) => e.key === "Enter" && scrollToMessage(replyData.id),
1582
- children: [
1583
- /* @__PURE__ */ jsx("span", { class: "pp-reply-sender", children: replyData.sender === "visitor" ? "You" : "Support" }),
1584
- /* @__PURE__ */ jsx("span", { class: "pp-reply-content", children: replyData.deleted ? "Message deleted" : /* @__PURE__ */ jsxs(Fragment2, { children: [
1585
- replyData.hasAttachment && /* @__PURE__ */ jsx("span", { class: "pp-reply-attachment-icon", children: replyData.attachmentType?.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
1586
- replyData.content ? /* @__PURE__ */ jsxs(Fragment2, { children: [
1587
- (replyData.content || "").slice(0, 50),
1588
- (replyData.content || "").length > 50 ? "..." : ""
1589
- ] }) : replyData.attachmentType?.startsWith("image/") ? "Photo" : "File"
1590
- ] }) })
1591
- ]
1592
- }
1593
- ),
1594
- isDeleted ? /* @__PURE__ */ jsxs("div", { class: "pp-message-content pp-deleted-content", children: [
1595
- /* @__PURE__ */ jsx("span", { class: "pp-deleted-icon", children: "\u{1F5D1}\uFE0F" }),
1596
- " Message deleted"
1597
- ] }) : /* @__PURE__ */ jsxs(Fragment2, { children: [
1598
- msg.content && /* @__PURE__ */ jsx("div", { class: "pp-message-content", children: msg.content }),
1599
- msg.attachments && msg.attachments.length > 0 && /* @__PURE__ */ jsx("div", { class: "pp-message-attachments", children: msg.attachments.map((att) => /* @__PURE__ */ jsx(AttachmentDisplay, { attachment: att }, att.id)) })
1600
- ] }),
1601
- /* @__PURE__ */ jsxs("div", { class: "pp-message-time", children: [
1602
- formatTime(msg.timestamp),
1603
- isEdited && !isDeleted && /* @__PURE__ */ jsx("span", { class: "pp-edited-badge", children: "edited" }),
1604
- msg.sender === "ai" && /* @__PURE__ */ jsx("span", { class: "pp-ai-badge", children: "AI" }),
1605
- msg.sender === "visitor" && !isDeleted && /* @__PURE__ */ jsx("span", { class: `pp-status pp-status-${msg.status ?? "sent"}`, children: /* @__PURE__ */ jsx(StatusIcon, { status: msg.status }) })
1606
- ] })
1607
- ]
1608
- }
1609
- )
2447
+ ]
2448
+ }
2449
+ )
2450
+ ] })
1610
2451
  ] }, msg.id);
1611
2452
  }),
1612
- isTyping && /* @__PURE__ */ jsxs("div", { class: "pp-message pp-message-operator pp-typing", children: [
1613
- /* @__PURE__ */ jsx("span", {}),
1614
- /* @__PURE__ */ jsx("span", {}),
1615
- /* @__PURE__ */ jsx("span", {})
2453
+ isTyping && /* @__PURE__ */ jsxs2("div", { class: "pp-message pp-message-operator pp-typing", children: [
2454
+ /* @__PURE__ */ jsx2("span", {}),
2455
+ /* @__PURE__ */ jsx2("span", {}),
2456
+ /* @__PURE__ */ jsx2("span", {})
1616
2457
  ] }),
1617
- /* @__PURE__ */ jsx("div", { ref: messagesEndRef })
2458
+ /* @__PURE__ */ jsx2("div", { ref: messagesEndRef })
1618
2459
  ] }),
1619
- messageMenu && /* @__PURE__ */ jsxs(
2460
+ messageMenu && /* @__PURE__ */ jsxs2(
1620
2461
  "div",
1621
2462
  {
1622
2463
  class: "pp-message-menu",
1623
2464
  style: { top: `${messageMenu.y}px`, left: `${messageMenu.x}px` },
1624
2465
  children: [
1625
- /* @__PURE__ */ jsxs("button", { onClick: () => handleReply(messageMenu.message), children: [
1626
- /* @__PURE__ */ jsx(ReplyIcon, { color: actionIconColor }),
2466
+ /* @__PURE__ */ jsxs2("button", { onClick: () => handleReply(messageMenu.message), children: [
2467
+ /* @__PURE__ */ jsx2(ReplyIcon, { color: actionIconColor }),
1627
2468
  " Reply"
1628
2469
  ] }),
1629
- messageMenu.message.sender === "visitor" && !messageMenu.message.deletedAt && /* @__PURE__ */ jsxs(Fragment2, { children: [
1630
- /* @__PURE__ */ jsxs("button", { onClick: () => handleStartEdit(messageMenu.message), children: [
1631
- /* @__PURE__ */ jsx(EditIcon, { color: actionIconColor }),
2470
+ messageMenu.message.sender === "visitor" && !messageMenu.message.deletedAt && /* @__PURE__ */ jsxs2(Fragment3, { children: [
2471
+ /* @__PURE__ */ jsxs2("button", { onClick: () => handleStartEdit(messageMenu.message), children: [
2472
+ /* @__PURE__ */ jsx2(EditIcon, { color: actionIconColor }),
1632
2473
  " Edit"
1633
2474
  ] }),
1634
- /* @__PURE__ */ jsxs("button", { class: "pp-menu-delete", onClick: () => handleDelete(messageMenu.message), children: [
1635
- /* @__PURE__ */ jsx(DeleteIcon, { color: "#ef4444" }),
2475
+ /* @__PURE__ */ jsxs2("button", { class: "pp-menu-delete", onClick: () => handleDelete(messageMenu.message), children: [
2476
+ /* @__PURE__ */ jsx2(DeleteIcon, { color: "#ef4444" }),
1636
2477
  " Delete"
1637
2478
  ] })
1638
2479
  ] })
1639
2480
  ]
1640
2481
  }
1641
2482
  ),
1642
- editingMessage && /* @__PURE__ */ jsxs("div", { class: "pp-edit-modal", children: [
1643
- /* @__PURE__ */ jsxs("div", { class: "pp-edit-header", children: [
1644
- /* @__PURE__ */ jsx("span", { children: "Edit message" }),
1645
- /* @__PURE__ */ jsx("button", { onClick: handleCancelEdit, children: /* @__PURE__ */ jsx(CloseIcon, {}) })
2483
+ editingMessage && /* @__PURE__ */ jsxs2("div", { class: "pp-edit-modal", children: [
2484
+ /* @__PURE__ */ jsxs2("div", { class: "pp-edit-header", children: [
2485
+ /* @__PURE__ */ jsx2("span", { children: "Edit message" }),
2486
+ /* @__PURE__ */ jsx2("button", { onClick: handleCancelEdit, children: /* @__PURE__ */ jsx2(CloseIcon, {}) })
1646
2487
  ] }),
1647
- /* @__PURE__ */ jsx(
2488
+ /* @__PURE__ */ jsx2(
1648
2489
  "textarea",
1649
2490
  {
1650
2491
  class: "pp-edit-input",
@@ -1653,41 +2494,41 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1653
2494
  autoFocus: true
1654
2495
  }
1655
2496
  ),
1656
- /* @__PURE__ */ jsxs("div", { class: "pp-edit-actions", children: [
1657
- /* @__PURE__ */ jsx("button", { class: "pp-edit-cancel", onClick: handleCancelEdit, children: "Cancel" }),
1658
- /* @__PURE__ */ jsx("button", { class: "pp-edit-save", onClick: handleSaveEdit, disabled: !editContent.trim(), children: "Save" })
2497
+ /* @__PURE__ */ jsxs2("div", { class: "pp-edit-actions", children: [
2498
+ /* @__PURE__ */ jsx2("button", { class: "pp-edit-cancel", onClick: handleCancelEdit, children: "Cancel" }),
2499
+ /* @__PURE__ */ jsx2("button", { class: "pp-edit-save", onClick: handleSaveEdit, disabled: !editContent.trim(), children: "Save" })
1659
2500
  ] })
1660
2501
  ] }),
1661
- replyingTo && /* @__PURE__ */ jsxs("div", { class: "pp-reply-preview", children: [
1662
- /* @__PURE__ */ jsxs("div", { class: "pp-reply-preview-content", children: [
1663
- /* @__PURE__ */ jsx("span", { class: "pp-reply-label", children: "Replying to" }),
1664
- /* @__PURE__ */ jsxs("span", { class: "pp-reply-text", children: [
1665
- replyingTo.attachments && replyingTo.attachments.length > 0 && /* @__PURE__ */ jsx("span", { class: "pp-reply-attachment-icon", children: replyingTo.attachments[0].mimeType.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
1666
- replyingTo.content ? /* @__PURE__ */ jsxs(Fragment2, { children: [
2502
+ replyingTo && /* @__PURE__ */ jsxs2("div", { class: "pp-reply-preview", children: [
2503
+ /* @__PURE__ */ jsxs2("div", { class: "pp-reply-preview-content", children: [
2504
+ /* @__PURE__ */ jsx2("span", { class: "pp-reply-label", children: "Replying to" }),
2505
+ /* @__PURE__ */ jsxs2("span", { class: "pp-reply-text", children: [
2506
+ replyingTo.attachments && replyingTo.attachments.length > 0 && /* @__PURE__ */ jsx2("span", { class: "pp-reply-attachment-icon", children: replyingTo.attachments[0].mimeType.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
2507
+ replyingTo.content ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
1667
2508
  replyingTo.content.slice(0, 50),
1668
2509
  replyingTo.content.length > 50 ? "..." : ""
1669
2510
  ] }) : replyingTo.attachments?.[0]?.mimeType.startsWith("image/") ? "Photo" : "File"
1670
2511
  ] })
1671
2512
  ] }),
1672
- /* @__PURE__ */ jsx("button", { class: "pp-reply-cancel", onClick: handleCancelReply, children: /* @__PURE__ */ jsx(CloseIcon, {}) })
2513
+ /* @__PURE__ */ jsx2("button", { class: "pp-reply-cancel", onClick: handleCancelReply, children: /* @__PURE__ */ jsx2(CloseIcon, {}) })
1673
2514
  ] }),
1674
- pendingAttachments.length > 0 && /* @__PURE__ */ jsx("div", { class: "pp-attachments-preview", children: pendingAttachments.map((pending) => /* @__PURE__ */ jsxs("div", { class: `pp-attachment-preview pp-attachment-${pending.status}`, children: [
1675
- pending.preview ? /* @__PURE__ */ jsx("img", { src: pending.preview, alt: pending.file.name, class: "pp-preview-img" }) : /* @__PURE__ */ jsx("div", { class: "pp-preview-file", children: /* @__PURE__ */ jsx(FileIcon, { mimeType: pending.file.type }) }),
1676
- /* @__PURE__ */ jsx(
2515
+ pendingAttachments.length > 0 && /* @__PURE__ */ jsx2("div", { class: "pp-attachments-preview", children: pendingAttachments.map((pending) => /* @__PURE__ */ jsxs2("div", { class: `pp-attachment-preview pp-attachment-${pending.status}`, children: [
2516
+ pending.preview ? /* @__PURE__ */ jsx2("img", { src: pending.preview, alt: pending.file.name, class: "pp-preview-img" }) : /* @__PURE__ */ jsx2("div", { class: "pp-preview-file", children: /* @__PURE__ */ jsx2(FileIcon, { mimeType: pending.file.type }) }),
2517
+ /* @__PURE__ */ jsx2(
1677
2518
  "button",
1678
2519
  {
1679
2520
  class: "pp-remove-attachment",
1680
2521
  onClick: () => handleRemoveAttachment(pending.id),
1681
2522
  "aria-label": "Remove attachment",
1682
2523
  type: "button",
1683
- children: /* @__PURE__ */ jsx(CloseIcon, {})
2524
+ children: /* @__PURE__ */ jsx2(CloseIcon, {})
1684
2525
  }
1685
2526
  ),
1686
- pending.status === "uploading" && /* @__PURE__ */ jsx("div", { class: "pp-upload-progress", style: { width: `${pending.progress}%` } }),
1687
- pending.status === "error" && /* @__PURE__ */ jsx("div", { class: "pp-upload-error", title: pending.error, children: "!" })
2527
+ pending.status === "uploading" && /* @__PURE__ */ jsx2("div", { class: "pp-upload-progress", style: { width: `${pending.progress}%` } }),
2528
+ pending.status === "error" && /* @__PURE__ */ jsx2("div", { class: "pp-upload-error", title: pending.error, children: "!" })
1688
2529
  ] }, pending.id)) }),
1689
- /* @__PURE__ */ jsxs("form", { class: "pp-input-form", onSubmit: handleSubmit, children: [
1690
- /* @__PURE__ */ jsx(
2530
+ !shouldShowPreChat && /* @__PURE__ */ jsxs2("form", { class: "pp-input-form", onSubmit: handleSubmit, children: [
2531
+ /* @__PURE__ */ jsx2(
1691
2532
  "input",
1692
2533
  {
1693
2534
  ref: (el) => {
@@ -1702,7 +2543,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1702
2543
  multiple: true
1703
2544
  }
1704
2545
  ),
1705
- /* @__PURE__ */ jsx(
2546
+ /* @__PURE__ */ jsx2(
1706
2547
  "button",
1707
2548
  {
1708
2549
  type: "button",
@@ -1710,10 +2551,10 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1710
2551
  onClick: () => fileInputRef.current?.click(),
1711
2552
  disabled: !isConnected || isUploading,
1712
2553
  "aria-label": "Attach file",
1713
- children: /* @__PURE__ */ jsx(AttachIcon, {})
2554
+ children: /* @__PURE__ */ jsx2(AttachIcon, {})
1714
2555
  }
1715
2556
  ),
1716
- /* @__PURE__ */ jsx(
2557
+ /* @__PURE__ */ jsx2(
1717
2558
  "input",
1718
2559
  {
1719
2560
  ref: inputRef,
@@ -1725,20 +2566,20 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1725
2566
  disabled: !isConnected
1726
2567
  }
1727
2568
  ),
1728
- /* @__PURE__ */ jsx(
2569
+ /* @__PURE__ */ jsx2(
1729
2570
  "button",
1730
2571
  {
1731
2572
  type: "submit",
1732
2573
  class: "pp-send-btn",
1733
2574
  disabled: !inputValue.trim() && pendingAttachments.filter((a) => a.status === "ready").length === 0 || !isConnected || isUploading,
1734
2575
  "aria-label": "Send message",
1735
- children: /* @__PURE__ */ jsx(SendIcon, {})
2576
+ children: /* @__PURE__ */ jsx2(SendIcon, {})
1736
2577
  }
1737
2578
  )
1738
2579
  ] }),
1739
- /* @__PURE__ */ jsxs("div", { class: "pp-footer", children: [
2580
+ /* @__PURE__ */ jsxs2("div", { class: "pp-footer", children: [
1740
2581
  "Powered by ",
1741
- /* @__PURE__ */ jsx("a", { href: "https://pocketping.io", target: "_blank", rel: "noopener", children: "PocketPing" })
2582
+ /* @__PURE__ */ jsx2("a", { href: "https://pocketping.io", target: "_blank", rel: "noopener", children: "PocketPing" })
1742
2583
  ] })
1743
2584
  ]
1744
2585
  }
@@ -1766,90 +2607,90 @@ function formatTime(timestamp) {
1766
2607
  return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
1767
2608
  }
1768
2609
  function ChatIcon() {
1769
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: /* @__PURE__ */ jsx("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) });
2610
+ return /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: /* @__PURE__ */ jsx2("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) });
1770
2611
  }
1771
2612
  function CloseIcon() {
1772
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1773
- /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1774
- /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2613
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2614
+ /* @__PURE__ */ jsx2("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2615
+ /* @__PURE__ */ jsx2("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1775
2616
  ] });
1776
2617
  }
1777
2618
  function SendIcon() {
1778
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1779
- /* @__PURE__ */ jsx("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
1780
- /* @__PURE__ */ jsx("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
2619
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2620
+ /* @__PURE__ */ jsx2("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
2621
+ /* @__PURE__ */ jsx2("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
1781
2622
  ] });
1782
2623
  }
1783
2624
  function StatusIcon({ status }) {
1784
2625
  if (!status || status === "sending" || status === "sent") {
1785
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check", children: /* @__PURE__ */ jsx("polyline", { points: "3 8 7 12 13 4" }) });
2626
+ return /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check", children: /* @__PURE__ */ jsx2("polyline", { points: "3 8 7 12 13 4" }) });
1786
2627
  }
1787
2628
  if (status === "delivered") {
1788
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 20 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check-double", children: [
1789
- /* @__PURE__ */ jsx("polyline", { points: "1 8 5 12 11 4" }),
1790
- /* @__PURE__ */ jsx("polyline", { points: "7 8 11 12 17 4" })
2629
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 20 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check-double", children: [
2630
+ /* @__PURE__ */ jsx2("polyline", { points: "1 8 5 12 11 4" }),
2631
+ /* @__PURE__ */ jsx2("polyline", { points: "7 8 11 12 17 4" })
1791
2632
  ] });
1792
2633
  }
1793
2634
  if (status === "read") {
1794
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 20 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check-double pp-check-read", children: [
1795
- /* @__PURE__ */ jsx("polyline", { points: "1 8 5 12 11 4" }),
1796
- /* @__PURE__ */ jsx("polyline", { points: "7 8 11 12 17 4" })
2635
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 20 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check-double pp-check-read", children: [
2636
+ /* @__PURE__ */ jsx2("polyline", { points: "1 8 5 12 11 4" }),
2637
+ /* @__PURE__ */ jsx2("polyline", { points: "7 8 11 12 17 4" })
1797
2638
  ] });
1798
2639
  }
1799
2640
  return null;
1800
2641
  }
1801
2642
  function AttachIcon() {
1802
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: /* @__PURE__ */ jsx("path", { d: "M21.44 11.05l-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" }) });
2643
+ return /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: /* @__PURE__ */ jsx2("path", { d: "M21.44 11.05l-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" }) });
1803
2644
  }
1804
2645
  function ReplyIcon({ color, size = 16 }) {
1805
2646
  const strokeColor = color || "currentColor";
1806
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: [
1807
- /* @__PURE__ */ jsx("polyline", { points: "9 17 4 12 9 7" }),
1808
- /* @__PURE__ */ jsx("path", { d: "M20 18v-2a4 4 0 0 0-4-4H4" })
2647
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: [
2648
+ /* @__PURE__ */ jsx2("polyline", { points: "9 17 4 12 9 7" }),
2649
+ /* @__PURE__ */ jsx2("path", { d: "M20 18v-2a4 4 0 0 0-4-4H4" })
1809
2650
  ] });
1810
2651
  }
1811
2652
  function EditIcon({ color, size = 16 }) {
1812
2653
  const strokeColor = color || "currentColor";
1813
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: /* @__PURE__ */ jsx("path", { d: "M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z" }) });
2654
+ return /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: /* @__PURE__ */ jsx2("path", { d: "M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z" }) });
1814
2655
  }
1815
2656
  function DeleteIcon({ color, size = 16 }) {
1816
2657
  const strokeColor = color || "currentColor";
1817
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: [
1818
- /* @__PURE__ */ jsx("polyline", { points: "3 6 5 6 21 6" }),
1819
- /* @__PURE__ */ jsx("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
2658
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: [
2659
+ /* @__PURE__ */ jsx2("polyline", { points: "3 6 5 6 21 6" }),
2660
+ /* @__PURE__ */ jsx2("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
1820
2661
  ] });
1821
2662
  }
1822
2663
  function FileIcon({ mimeType }) {
1823
2664
  if (mimeType === "application/pdf") {
1824
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1825
- /* @__PURE__ */ jsx("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1826
- /* @__PURE__ */ jsx("polyline", { points: "14 2 14 8 20 8" }),
1827
- /* @__PURE__ */ jsx("path", { d: "M9 15h6" }),
1828
- /* @__PURE__ */ jsx("path", { d: "M9 11h6" })
2665
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2666
+ /* @__PURE__ */ jsx2("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
2667
+ /* @__PURE__ */ jsx2("polyline", { points: "14 2 14 8 20 8" }),
2668
+ /* @__PURE__ */ jsx2("path", { d: "M9 15h6" }),
2669
+ /* @__PURE__ */ jsx2("path", { d: "M9 11h6" })
1829
2670
  ] });
1830
2671
  }
1831
2672
  if (mimeType.startsWith("audio/")) {
1832
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1833
- /* @__PURE__ */ jsx("path", { d: "M9 18V5l12-2v13" }),
1834
- /* @__PURE__ */ jsx("circle", { cx: "6", cy: "18", r: "3" }),
1835
- /* @__PURE__ */ jsx("circle", { cx: "18", cy: "16", r: "3" })
2673
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2674
+ /* @__PURE__ */ jsx2("path", { d: "M9 18V5l12-2v13" }),
2675
+ /* @__PURE__ */ jsx2("circle", { cx: "6", cy: "18", r: "3" }),
2676
+ /* @__PURE__ */ jsx2("circle", { cx: "18", cy: "16", r: "3" })
1836
2677
  ] });
1837
2678
  }
1838
2679
  if (mimeType.startsWith("video/")) {
1839
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1840
- /* @__PURE__ */ jsx("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2.18", ry: "2.18" }),
1841
- /* @__PURE__ */ jsx("line", { x1: "7", y1: "2", x2: "7", y2: "22" }),
1842
- /* @__PURE__ */ jsx("line", { x1: "17", y1: "2", x2: "17", y2: "22" }),
1843
- /* @__PURE__ */ jsx("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
1844
- /* @__PURE__ */ jsx("line", { x1: "2", y1: "7", x2: "7", y2: "7" }),
1845
- /* @__PURE__ */ jsx("line", { x1: "2", y1: "17", x2: "7", y2: "17" }),
1846
- /* @__PURE__ */ jsx("line", { x1: "17", y1: "17", x2: "22", y2: "17" }),
1847
- /* @__PURE__ */ jsx("line", { x1: "17", y1: "7", x2: "22", y2: "7" })
2680
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2681
+ /* @__PURE__ */ jsx2("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2.18", ry: "2.18" }),
2682
+ /* @__PURE__ */ jsx2("line", { x1: "7", y1: "2", x2: "7", y2: "22" }),
2683
+ /* @__PURE__ */ jsx2("line", { x1: "17", y1: "2", x2: "17", y2: "22" }),
2684
+ /* @__PURE__ */ jsx2("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
2685
+ /* @__PURE__ */ jsx2("line", { x1: "2", y1: "7", x2: "7", y2: "7" }),
2686
+ /* @__PURE__ */ jsx2("line", { x1: "2", y1: "17", x2: "7", y2: "17" }),
2687
+ /* @__PURE__ */ jsx2("line", { x1: "17", y1: "17", x2: "22", y2: "17" }),
2688
+ /* @__PURE__ */ jsx2("line", { x1: "17", y1: "7", x2: "22", y2: "7" })
1848
2689
  ] });
1849
2690
  }
1850
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1851
- /* @__PURE__ */ jsx("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1852
- /* @__PURE__ */ jsx("polyline", { points: "14 2 14 8 20 8" })
2691
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2692
+ /* @__PURE__ */ jsx2("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
2693
+ /* @__PURE__ */ jsx2("polyline", { points: "14 2 14 8 20 8" })
1853
2694
  ] });
1854
2695
  }
1855
2696
  function AttachmentDisplay({ attachment }) {
@@ -1862,22 +2703,22 @@ function AttachmentDisplay({ attachment }) {
1862
2703
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
1863
2704
  };
1864
2705
  if (isImage) {
1865
- return /* @__PURE__ */ jsx("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-image", children: /* @__PURE__ */ jsx("img", { src: attachment.thumbnailUrl || attachment.url, alt: attachment.filename }) });
2706
+ return /* @__PURE__ */ jsx2("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-image", children: /* @__PURE__ */ jsx2("img", { src: attachment.thumbnailUrl || attachment.url, alt: attachment.filename }) });
1866
2707
  }
1867
2708
  if (isAudio) {
1868
- return /* @__PURE__ */ jsxs("div", { class: "pp-attachment pp-attachment-audio", children: [
1869
- /* @__PURE__ */ jsx("audio", { controls: true, preload: "metadata", children: /* @__PURE__ */ jsx("source", { src: attachment.url, type: attachment.mimeType }) }),
1870
- /* @__PURE__ */ jsx("span", { class: "pp-attachment-name", children: attachment.filename })
2709
+ return /* @__PURE__ */ jsxs2("div", { class: "pp-attachment pp-attachment-audio", children: [
2710
+ /* @__PURE__ */ jsx2("audio", { controls: true, preload: "metadata", children: /* @__PURE__ */ jsx2("source", { src: attachment.url, type: attachment.mimeType }) }),
2711
+ /* @__PURE__ */ jsx2("span", { class: "pp-attachment-name", children: attachment.filename })
1871
2712
  ] });
1872
2713
  }
1873
2714
  if (isVideo) {
1874
- return /* @__PURE__ */ jsx("div", { class: "pp-attachment pp-attachment-video", children: /* @__PURE__ */ jsx("video", { controls: true, preload: "metadata", children: /* @__PURE__ */ jsx("source", { src: attachment.url, type: attachment.mimeType }) }) });
2715
+ return /* @__PURE__ */ jsx2("div", { class: "pp-attachment pp-attachment-video", children: /* @__PURE__ */ jsx2("video", { controls: true, preload: "metadata", children: /* @__PURE__ */ jsx2("source", { src: attachment.url, type: attachment.mimeType }) }) });
1875
2716
  }
1876
- return /* @__PURE__ */ jsxs("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-file", children: [
1877
- /* @__PURE__ */ jsx(FileIcon, { mimeType: attachment.mimeType }),
1878
- /* @__PURE__ */ jsxs("div", { class: "pp-attachment-info", children: [
1879
- /* @__PURE__ */ jsx("span", { class: "pp-attachment-name", children: attachment.filename }),
1880
- /* @__PURE__ */ jsx("span", { class: "pp-attachment-size", children: formatSize(attachment.size) })
2717
+ return /* @__PURE__ */ jsxs2("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-file", children: [
2718
+ /* @__PURE__ */ jsx2(FileIcon, { mimeType: attachment.mimeType }),
2719
+ /* @__PURE__ */ jsxs2("div", { class: "pp-attachment-info", children: [
2720
+ /* @__PURE__ */ jsx2("span", { class: "pp-attachment-name", children: attachment.filename }),
2721
+ /* @__PURE__ */ jsx2("span", { class: "pp-attachment-size", children: formatSize(attachment.size) })
1881
2722
  ] })
1882
2723
  ] });
1883
2724
  }
@@ -1943,7 +2784,8 @@ var PocketPingClient = class {
1943
2784
  visitorId: response.visitorId,
1944
2785
  operatorOnline: response.operatorOnline ?? false,
1945
2786
  messages: response.messages ?? [],
1946
- identity: response.identity || storedIdentity || void 0
2787
+ identity: response.identity || storedIdentity || void 0,
2788
+ preChatForm: response.preChatForm
1947
2789
  };
1948
2790
  if (response.operatorName) {
1949
2791
  this.config.operatorName = response.operatorName;
@@ -1954,6 +2796,18 @@ var PocketPingClient = class {
1954
2796
  if (response.primaryColor) {
1955
2797
  this.config.primaryColor = response.primaryColor;
1956
2798
  }
2799
+ if (response.headerColor) {
2800
+ this.config.headerColor = response.headerColor;
2801
+ }
2802
+ if (response.footerColor) {
2803
+ this.config.footerColor = response.footerColor;
2804
+ }
2805
+ if (response.chatBackground) {
2806
+ this.config.chatBackground = response.chatBackground;
2807
+ }
2808
+ if (response.toggleColor) {
2809
+ this.config.toggleColor = response.toggleColor;
2810
+ }
1957
2811
  if (response.welcomeMessage) {
1958
2812
  this.config.welcomeMessage = response.welcomeMessage;
1959
2813
  }
@@ -1961,6 +2815,10 @@ var PocketPingClient = class {
1961
2815
  operatorName: this.config.operatorName,
1962
2816
  operatorAvatar: this.config.operatorAvatar,
1963
2817
  primaryColor: this.config.primaryColor,
2818
+ headerColor: this.config.headerColor,
2819
+ footerColor: this.config.footerColor,
2820
+ chatBackground: this.config.chatBackground,
2821
+ toggleColor: this.config.toggleColor,
1964
2822
  welcomeMessage: this.config.welcomeMessage
1965
2823
  });
1966
2824
  this.storeSessionId(response.sessionId);
@@ -2299,6 +3157,36 @@ var PocketPingClient = class {
2299
3157
  }
2300
3158
  }
2301
3159
  }
3160
+ /**
3161
+ * Submit pre-chat form data (email and/or phone)
3162
+ * @param data - Form data containing email and/or phone
3163
+ */
3164
+ async submitPreChat(data) {
3165
+ if (!this.session) {
3166
+ throw new Error("[PocketPing] Not connected");
3167
+ }
3168
+ if (!data.email && !data.phone) {
3169
+ throw new Error("[PocketPing] Either email or phone is required");
3170
+ }
3171
+ try {
3172
+ await this.fetch("/prechat", {
3173
+ method: "POST",
3174
+ body: JSON.stringify({
3175
+ sessionId: this.session.sessionId,
3176
+ email: data.email,
3177
+ phone: data.phone,
3178
+ phoneCountry: data.phoneCountry
3179
+ })
3180
+ });
3181
+ if (this.session.preChatForm) {
3182
+ this.session.preChatForm.completed = true;
3183
+ }
3184
+ this.emit("preChatCompleted", data);
3185
+ } catch (err) {
3186
+ console.error("[PocketPing] Failed to submit pre-chat form:", err);
3187
+ throw err;
3188
+ }
3189
+ }
2302
3190
  /**
2303
3191
  * Reset the user identity and optionally start a new session
2304
3192
  * Call on user logout to clear user data
@@ -2948,6 +3836,12 @@ var PocketPingClient = class {
2948
3836
  this.session.messages.push(message);
2949
3837
  this.emit("message", message);
2950
3838
  this.config.onMessage?.(message);
3839
+ if (message.sender !== "visitor" && !this.isOpen) {
3840
+ const autoOpen = this.config.autoOpenOnMessage ?? true;
3841
+ if (autoOpen) {
3842
+ this.setOpen(true);
3843
+ }
3844
+ }
2951
3845
  }
2952
3846
  }
2953
3847
  if (message.sender !== "visitor") {
@@ -3106,6 +4000,12 @@ var PocketPingClient = class {
3106
4000
  this.session.messages.push(message);
3107
4001
  this.emit("message", message);
3108
4002
  this.config.onMessage?.(message);
4003
+ if (message.sender !== "visitor" && !this.isOpen) {
4004
+ const autoOpen = this.config.autoOpenOnMessage ?? true;
4005
+ if (autoOpen) {
4006
+ this.setOpen(true);
4007
+ }
4008
+ }
3109
4009
  }
3110
4010
  }
3111
4011
  } catch (err) {