@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.cjs CHANGED
@@ -44,11 +44,41 @@ var import_preact2 = require("preact");
44
44
 
45
45
  // src/components/ChatWidget.tsx
46
46
  var import_preact = require("preact");
47
- var import_hooks = require("preact/hooks");
47
+ var import_hooks2 = require("preact/hooks");
48
48
 
49
49
  // src/components/styles.ts
50
- function styles(primaryColor, theme) {
50
+ function resolveThemeColor(color, isDark, defaultLight, defaultDark) {
51
+ if (!color) {
52
+ return isDark ? defaultDark : defaultLight;
53
+ }
54
+ if (typeof color === "string") {
55
+ return color;
56
+ }
57
+ return isDark ? color.dark : color.light;
58
+ }
59
+ function styles(options) {
60
+ const { primaryColor, theme, headerColor, footerColor, chatBackground, toggleColor } = options;
51
61
  const isDark = theme === "dark";
62
+ const resolvedHeaderColor = resolveThemeColor(headerColor, isDark, "#008069", "#202c33");
63
+ const resolvedFooterColor = resolveThemeColor(footerColor, isDark, "#f0f2f5", "#202c33");
64
+ const resolvedToggleColor = resolveThemeColor(toggleColor, isDark, "#25d366", "#25d366");
65
+ const resolvedToggleHoverColor = resolvedToggleColor !== "#25d366" ? adjustBrightness(resolvedToggleColor, -10) : "#22c55e";
66
+ 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")`;
67
+ 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")`;
68
+ const resolvedChatBg = resolveThemeColor(chatBackground, isDark, "whatsapp", "whatsapp");
69
+ const chatBgColor = isDark ? "#0b141a" : "#e5ddd5";
70
+ let chatBgImage = whatsappPattern;
71
+ let chatBgSize = "auto";
72
+ if (resolvedChatBg === "plain") {
73
+ chatBgImage = "none";
74
+ } else if (resolvedChatBg === "dots") {
75
+ chatBgImage = dotsPattern;
76
+ } else if (resolvedChatBg === "whatsapp" || !resolvedChatBg) {
77
+ chatBgImage = whatsappPattern;
78
+ } else if (resolvedChatBg.startsWith("http") || resolvedChatBg.startsWith("/") || resolvedChatBg.startsWith("data:")) {
79
+ chatBgImage = `url("${resolvedChatBg}")`;
80
+ chatBgSize = "cover";
81
+ }
52
82
  const colors = {
53
83
  bg: isDark ? "#1f2937" : "#ffffff",
54
84
  bgSecondary: isDark ? "#374151" : "#f3f4f6",
@@ -57,6 +87,13 @@ function styles(primaryColor, theme) {
57
87
  border: isDark ? "#4b5563" : "#e5e7eb",
58
88
  messageBg: isDark ? "#374151" : "#f3f4f6"
59
89
  };
90
+ function adjustBrightness(hex, percent) {
91
+ const num = parseInt(hex.replace("#", ""), 16);
92
+ const r = Math.min(255, Math.max(0, (num >> 16) + percent));
93
+ const g = Math.min(255, Math.max(0, (num >> 8 & 255) + percent));
94
+ const b = Math.min(255, Math.max(0, (num & 255) + percent));
95
+ return "#" + (16777216 + (r << 16) + (g << 8) + b).toString(16).slice(1);
96
+ }
60
97
  return `
61
98
  #pocketping-container {
62
99
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
@@ -65,31 +102,47 @@ function styles(primaryColor, theme) {
65
102
  color: ${colors.text};
66
103
  }
67
104
 
105
+ #pocketping-container,
106
+ #pocketping-container * {
107
+ box-sizing: border-box;
108
+ }
109
+
110
+ #pocketping-container img,
111
+ #pocketping-container video {
112
+ max-width: 100%;
113
+ height: auto;
114
+ }
115
+
68
116
  .pp-toggle {
69
117
  position: fixed;
70
- width: 56px;
71
- height: 56px;
118
+ width: 60px;
119
+ height: 60px;
72
120
  border-radius: 50%;
73
- background: ${primaryColor};
121
+ background: ${resolvedToggleColor};
74
122
  color: white;
75
123
  border: none;
76
124
  cursor: pointer;
77
125
  display: flex;
78
126
  align-items: center;
79
127
  justify-content: center;
80
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
81
- transition: transform 0.2s, box-shadow 0.2s;
128
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1);
129
+ transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
82
130
  z-index: 9999;
83
131
  }
84
132
 
85
133
  .pp-toggle:hover {
86
- transform: scale(1.05);
87
- box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
134
+ transform: scale(1.08);
135
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(0, 0, 0, 0.15);
136
+ background: ${resolvedToggleHoverColor};
137
+ }
138
+
139
+ .pp-toggle:active {
140
+ transform: scale(0.95);
88
141
  }
89
142
 
90
143
  .pp-toggle svg {
91
- width: 24px;
92
- height: 24px;
144
+ width: 28px;
145
+ height: 28px;
93
146
  }
94
147
 
95
148
  .pp-toggle.pp-bottom-right {
@@ -140,13 +193,13 @@ function styles(primaryColor, theme) {
140
193
 
141
194
  .pp-window {
142
195
  position: fixed;
143
- width: 380px;
144
- height: 520px;
196
+ width: 375px;
197
+ height: 550px;
145
198
  max-height: calc(100vh - 100px);
146
199
  max-height: calc(100dvh - 100px);
147
- background: ${colors.bg};
148
- border-radius: 16px;
149
- box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
200
+ background: ${isDark ? "#111b21" : "#ffffff"};
201
+ border-radius: 12px;
202
+ box-shadow: 0 12px 28px rgba(0, 0, 0, 0.2), 0 4px 10px rgba(0, 0, 0, 0.15);
150
203
  display: flex;
151
204
  flex-direction: column;
152
205
  overflow: hidden;
@@ -155,12 +208,12 @@ function styles(primaryColor, theme) {
155
208
  }
156
209
 
157
210
  .pp-window.pp-bottom-right {
158
- bottom: 88px;
211
+ bottom: 20px;
159
212
  right: 20px;
160
213
  }
161
214
 
162
215
  .pp-window.pp-bottom-left {
163
- bottom: 88px;
216
+ bottom: 20px;
164
217
  left: 20px;
165
218
  }
166
219
 
@@ -169,9 +222,9 @@ function styles(primaryColor, theme) {
169
222
  width: calc(100vw - 20px);
170
223
  height: auto;
171
224
  min-height: 300px;
172
- max-height: calc(100vh - 100px);
173
- max-height: calc(100svh - 100px); /* svh = small viewport, excludes keyboard */
174
- bottom: 80px;
225
+ max-height: calc(100vh - 40px);
226
+ max-height: calc(100svh - 40px); /* svh = small viewport, excludes keyboard */
227
+ bottom: 10px;
175
228
  right: 10px;
176
229
  left: 10px;
177
230
  border-radius: 12px;
@@ -189,35 +242,38 @@ function styles(primaryColor, theme) {
189
242
  display: flex;
190
243
  align-items: center;
191
244
  justify-content: space-between;
192
- padding: 12px 14px;
193
- background: ${primaryColor};
245
+ padding: 10px 16px;
246
+ background: ${resolvedHeaderColor};
194
247
  color: white;
195
248
  }
196
249
 
197
250
  .pp-header-info {
198
251
  display: flex;
199
252
  align-items: center;
200
- gap: 10px;
253
+ gap: 12px;
201
254
  }
202
255
 
203
256
  .pp-avatar {
204
- width: 36px;
205
- height: 36px;
257
+ width: 40px;
258
+ height: 40px;
206
259
  border-radius: 50%;
207
260
  object-fit: cover;
261
+ border: 2px solid rgba(255, 255, 255, 0.2);
208
262
  }
209
263
 
210
264
  .pp-header-title {
211
- font-weight: 600;
212
- font-size: 15px;
265
+ font-weight: 500;
266
+ font-size: 16px;
267
+ letter-spacing: 0.1px;
213
268
  }
214
269
 
215
270
  .pp-header-status {
216
- font-size: 11px;
217
- opacity: 0.85;
271
+ font-size: 13px;
272
+ opacity: 0.9;
218
273
  display: flex;
219
274
  align-items: center;
220
- gap: 4px;
275
+ gap: 5px;
276
+ font-weight: 400;
221
277
  }
222
278
 
223
279
  .pp-status-dot {
@@ -228,7 +284,8 @@ function styles(primaryColor, theme) {
228
284
  }
229
285
 
230
286
  .pp-status-dot.pp-online {
231
- background: #22c55e;
287
+ background: #25d366;
288
+ box-shadow: 0 0 0 2px rgba(37, 211, 102, 0.3);
232
289
  }
233
290
 
234
291
  .pp-close-btn {
@@ -236,13 +293,13 @@ function styles(primaryColor, theme) {
236
293
  border: none;
237
294
  color: white;
238
295
  cursor: pointer;
239
- padding: 4px;
240
- border-radius: 4px;
241
- opacity: 0.8;
242
- transition: opacity 0.2s;
296
+ padding: 8px;
297
+ border-radius: 50%;
298
+ opacity: 0.9;
299
+ transition: opacity 0.2s, background 0.2s;
243
300
  flex-shrink: 0;
244
- width: 28px;
245
- height: 28px;
301
+ width: 36px;
302
+ height: 36px;
246
303
  display: flex;
247
304
  align-items: center;
248
305
  justify-content: center;
@@ -250,157 +307,199 @@ function styles(primaryColor, theme) {
250
307
 
251
308
  .pp-close-btn:hover {
252
309
  opacity: 1;
310
+ background: rgba(255, 255, 255, 0.1);
253
311
  }
254
312
 
255
313
  .pp-close-btn svg {
256
- width: 16px;
257
- height: 16px;
314
+ width: 18px;
315
+ height: 18px;
258
316
  }
259
317
 
260
318
  .pp-messages {
261
319
  flex: 1;
262
320
  overflow-y: auto;
263
- padding: 12px;
321
+ padding: 16px 12px;
264
322
  display: flex;
265
323
  flex-direction: column;
266
- gap: 3px;
324
+ gap: 2px;
325
+ overscroll-behavior: contain;
326
+ -webkit-overflow-scrolling: touch;
327
+ position: relative;
328
+ background: ${chatBgColor};
329
+ background-image: ${chatBgImage};
330
+ background-size: ${chatBgSize};
331
+ background-position: center;
267
332
  }
268
333
 
269
334
  .pp-welcome {
270
335
  text-align: center;
271
- color: ${colors.textSecondary};
272
- padding: 24px;
273
- font-size: 13px;
336
+ color: ${isDark ? "#8696a0" : "#667781"};
337
+ padding: 32px 24px;
338
+ font-size: 14px;
339
+ line-height: 1.5;
340
+ background: ${isDark ? "rgba(17, 27, 33, 0.9)" : "rgba(255, 255, 255, 0.95)"};
341
+ margin: 12px;
342
+ border-radius: 8px;
343
+ box-shadow: 0 1px 0.5px rgba(0, 0, 0, 0.13);
274
344
  }
275
345
 
276
346
  .pp-date-separator {
277
347
  display: flex;
278
348
  align-items: center;
279
349
  justify-content: center;
280
- margin: 16px 0 12px;
350
+ margin: 12px 0;
281
351
  }
282
352
 
283
353
  .pp-date-separator span {
284
- background: ${colors.bgSecondary};
285
- color: ${colors.textSecondary};
286
- font-size: 11px;
287
- padding: 4px 12px;
288
- border-radius: 12px;
289
- font-weight: 500;
354
+ background: ${isDark ? "rgba(17, 27, 33, 0.9)" : "rgba(255, 255, 255, 0.95)"};
355
+ color: ${isDark ? "#8696a0" : "#54656f"};
356
+ font-size: 12px;
357
+ padding: 6px 12px;
358
+ border-radius: 8px;
359
+ font-weight: 400;
360
+ box-shadow: 0 1px 0.5px rgba(0, 0, 0, 0.13);
361
+ text-transform: uppercase;
362
+ letter-spacing: 0.3px;
290
363
  }
291
364
 
292
- .pp-message {
293
- max-width: 85%;
294
- padding: 6px 10px;
295
- border-radius: 12px;
296
- word-wrap: break-word;
365
+ /* Swipe container for mobile actions */
366
+ .pp-message-swipe-container {
297
367
  position: relative;
298
- user-select: text;
299
- -webkit-user-select: text;
300
- font-size: 14px;
301
- line-height: 1.35;
368
+ display: flex;
369
+ align-items: stretch;
370
+ overflow: visible;
371
+ touch-action: pan-y;
302
372
  }
303
373
 
304
- /* Hover actions container - positioned above message (Slack style) */
305
- .pp-message-actions {
374
+ .pp-swipe-left {
375
+ justify-content: flex-end;
376
+ }
377
+
378
+ .pp-swipe-right {
379
+ justify-content: flex-start;
380
+ }
381
+
382
+ .pp-swipe-actions {
306
383
  position: absolute;
307
- top: -28px;
308
- display: flex;
309
- gap: 2px;
310
- background: ${colors.bg};
311
- border: 1px solid ${colors.border};
312
- border-radius: 6px;
313
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
314
- padding: 2px;
384
+ top: 0;
385
+ bottom: 0;
386
+ display: none; /* Hidden by default - only show on mobile with touch */
387
+ align-items: center;
388
+ gap: 4px;
315
389
  opacity: 0;
316
- animation: pp-actions-fade-in 0.12s ease forwards;
317
- z-index: 10;
318
- /* Reset color inheritance from message */
319
- color: ${colors.textSecondary};
390
+ pointer-events: none;
320
391
  }
321
392
 
322
- @keyframes pp-actions-fade-in {
323
- from { opacity: 0; transform: translateY(4px); }
324
- to { opacity: 1; transform: translateY(0); }
393
+ /* Only show swipe actions on touch devices */
394
+ @media (hover: none) and (pointer: coarse) {
395
+ .pp-swipe-actions {
396
+ display: flex;
397
+ }
325
398
  }
326
399
 
327
- /* Visitor messages: actions aligned right */
328
- .pp-actions-left {
329
- right: 0;
400
+ .pp-swipe-left .pp-swipe-actions {
401
+ right: -80px; /* Hidden off-screen to the right */
402
+ left: auto;
403
+ padding-right: 8px;
330
404
  }
331
405
 
332
- /* Operator messages: actions aligned left */
333
- .pp-actions-right {
334
- left: 0;
406
+ .pp-swipe-right .pp-swipe-actions {
407
+ left: -80px; /* Hidden off-screen to the left */
408
+ right: auto;
409
+ padding-left: 8px;
335
410
  }
336
411
 
337
- .pp-message-actions .pp-action-btn {
338
- width: 24px;
339
- height: 24px;
412
+ .pp-swipe-action {
413
+ width: 32px;
414
+ height: 32px;
340
415
  border: none;
341
- background: transparent;
342
- border-radius: 4px;
416
+ border-radius: 50%;
343
417
  cursor: pointer;
344
418
  display: flex;
345
419
  align-items: center;
346
420
  justify-content: center;
347
- color: ${colors.textSecondary} !important;
348
- transition: background 0.1s, color 0.1s;
349
- }
350
-
351
- .pp-message-actions .pp-action-btn:hover {
352
- background: ${colors.bgSecondary};
353
- color: ${colors.text} !important;
354
- }
355
-
356
- .pp-message-actions .pp-action-btn svg {
357
- width: 14px;
358
- height: 14px;
359
- stroke: ${colors.textSecondary};
360
- }
361
-
362
- .pp-message-actions .pp-action-btn:hover svg {
363
- stroke: ${colors.text};
421
+ opacity: 0.9;
364
422
  }
365
423
 
366
- .pp-message-actions .pp-action-delete:hover {
367
- background: #fef2f2;
424
+ .pp-swipe-action svg {
425
+ width: 16px;
426
+ height: 16px;
368
427
  }
369
428
 
370
- .pp-message-actions .pp-action-delete:hover svg {
371
- stroke: #ef4444;
429
+ .pp-swipe-reply {
430
+ background: ${primaryColor};
372
431
  }
373
432
 
374
- .pp-theme-dark .pp-message-actions .pp-action-delete:hover {
375
- background: #7f1d1d;
433
+ .pp-swipe-edit {
434
+ background: #3b82f6;
376
435
  }
377
436
 
378
- .pp-theme-dark .pp-message-actions .pp-action-delete:hover svg {
379
- stroke: #fca5a5;
437
+ .pp-swipe-delete {
438
+ background: #ef4444;
380
439
  }
381
440
 
382
- /* Hide hover actions on mobile */
383
- @media (hover: none) and (pointer: coarse) {
384
- .pp-message-actions {
385
- display: none;
386
- }
441
+ .pp-message {
442
+ max-width: 80%;
443
+ padding: 6px 8px 6px 9px;
444
+ border-radius: 8px;
445
+ word-wrap: break-word;
446
+ overflow-wrap: break-word;
447
+ position: relative;
448
+ user-select: text;
449
+ -webkit-user-select: text;
450
+ font-size: 14.2px;
451
+ line-height: 1.4;
452
+ display: block; /* Block for proper float behavior */
453
+ will-change: transform;
454
+ box-shadow: 0 1px 0.5px rgba(0, 0, 0, 0.13);
387
455
  }
388
456
 
389
457
  .pp-message-visitor {
390
458
  align-self: flex-end;
391
- background: ${primaryColor};
392
- color: white;
393
- border-bottom-right-radius: 3px;
394
- margin-left: 32px;
459
+ background: ${isDark ? "#005c4b" : "#d9fdd3"};
460
+ color: ${isDark ? "#e9edef" : "#111b21"};
461
+ border-top-right-radius: 8px;
462
+ border-top-left-radius: 8px;
463
+ border-bottom-left-radius: 8px;
464
+ border-bottom-right-radius: 0;
465
+ margin-left: 48px;
466
+ }
467
+
468
+ /* WhatsApp-style tail for visitor messages */
469
+ .pp-message-visitor::after {
470
+ content: '';
471
+ position: absolute;
472
+ right: -7px;
473
+ bottom: 0;
474
+ width: 8px;
475
+ height: 13px;
476
+ background: ${isDark ? "#005c4b" : "#d9fdd3"};
477
+ clip-path: path('M 0 0 L 0 13 L 8 13 Q 2 10 0 0');
395
478
  }
396
479
 
397
480
  .pp-message-operator,
398
481
  .pp-message-ai {
399
482
  align-self: flex-start;
400
- background: ${colors.messageBg};
401
- color: ${colors.text};
402
- border-bottom-left-radius: 3px;
403
- margin-right: 32px;
483
+ background: ${isDark ? "#202c33" : "#ffffff"};
484
+ color: ${isDark ? "#e9edef" : "#111b21"};
485
+ border-top-right-radius: 8px;
486
+ border-top-left-radius: 8px;
487
+ border-bottom-right-radius: 8px;
488
+ border-bottom-left-radius: 0;
489
+ margin-right: 48px;
490
+ }
491
+
492
+ /* WhatsApp-style tail for operator messages */
493
+ .pp-message-operator::after,
494
+ .pp-message-ai::after {
495
+ content: '';
496
+ position: absolute;
497
+ left: -7px;
498
+ bottom: 0;
499
+ width: 8px;
500
+ height: 13px;
501
+ background: ${isDark ? "#202c33" : "#ffffff"};
502
+ clip-path: path('M 8 0 L 8 13 L 0 13 Q 6 10 8 0');
404
503
  }
405
504
 
406
505
  /* Add spacing between different senders */
@@ -415,23 +514,38 @@ function styles(primaryColor, theme) {
415
514
  display: inline;
416
515
  }
417
516
 
517
+ /* WhatsApp-style inline timestamp - floats to the right */
418
518
  .pp-message-time {
419
- font-size: 10px;
420
- opacity: 0.6;
519
+ font-size: 11px;
421
520
  display: inline-flex;
422
521
  align-items: center;
423
522
  gap: 3px;
424
523
  float: right;
425
- margin-left: 8px;
524
+ margin: 3px 0 0 12px;
525
+ color: ${isDark ? "rgba(255,255,255,0.6)" : "rgba(0,0,0,0.45)"};
526
+ white-space: nowrap;
527
+ }
528
+
529
+ .pp-message-visitor .pp-message-time {
530
+ color: ${isDark ? "rgba(255,255,255,0.7)" : "rgba(0,0,0,0.45)"};
531
+ }
532
+
533
+ /* Timestamp for attachment-only messages */
534
+ .pp-attachment-time {
535
+ float: none;
536
+ display: flex;
537
+ justify-content: flex-end;
426
538
  margin-top: 4px;
427
539
  }
428
540
 
429
541
  .pp-ai-badge {
430
- background: rgba(0, 0, 0, 0.1);
431
- padding: 1px 4px;
542
+ background: ${isDark ? "rgba(255,255,255,0.15)" : "rgba(0, 0, 0, 0.08)"};
543
+ padding: 2px 5px;
432
544
  border-radius: 4px;
433
- font-size: 10px;
545
+ font-size: 9px;
434
546
  font-weight: 600;
547
+ text-transform: uppercase;
548
+ letter-spacing: 0.3px;
435
549
  }
436
550
 
437
551
  .pp-status {
@@ -447,11 +561,11 @@ function styles(primaryColor, theme) {
447
561
 
448
562
  .pp-check,
449
563
  .pp-check-double {
450
- stroke: rgba(255, 255, 255, 0.7);
564
+ stroke: ${isDark ? "rgba(255, 255, 255, 0.5)" : "rgba(0, 0, 0, 0.35)"};
451
565
  }
452
566
 
453
567
  .pp-check-read {
454
- stroke: #34b7f1;
568
+ stroke: #53bdeb;
455
569
  }
456
570
 
457
571
  .pp-status-sending .pp-check {
@@ -460,14 +574,15 @@ function styles(primaryColor, theme) {
460
574
 
461
575
  .pp-typing {
462
576
  display: flex;
463
- gap: 3px;
464
- padding: 8px 12px;
577
+ gap: 4px;
578
+ padding: 12px 14px;
579
+ align-items: center;
465
580
  }
466
581
 
467
582
  .pp-typing span {
468
- width: 6px;
469
- height: 6px;
470
- background: ${colors.textSecondary};
583
+ width: 7px;
584
+ height: 7px;
585
+ background: ${isDark ? "#8696a0" : "#667781"};
471
586
  border-radius: 50%;
472
587
  animation: pp-bounce 1.4s infinite ease-in-out both;
473
588
  }
@@ -482,57 +597,56 @@ function styles(primaryColor, theme) {
482
597
 
483
598
  .pp-input-form {
484
599
  display: flex;
485
- padding: 10px 12px;
600
+ padding: 8px 10px;
486
601
  gap: 8px;
487
- border-top: 1px solid ${colors.border};
602
+ background: ${resolvedFooterColor};
488
603
  align-items: center;
489
604
  }
490
605
 
491
606
  .pp-input {
492
607
  flex: 1;
493
608
  min-width: 0;
494
- height: 40px;
495
- line-height: 40px;
496
- padding: 0 16px;
497
- border: 1px solid ${colors.border};
498
- border-radius: 20px;
499
- background: ${colors.bg};
500
- color: ${colors.text};
501
- font-size: 14px;
609
+ height: 42px;
610
+ line-height: 42px;
611
+ padding: 0 14px;
612
+ border: none;
613
+ border-radius: 8px;
614
+ background: ${isDark ? "#2a3942" : "#ffffff"};
615
+ color: ${isDark ? "#e9edef" : "#111b21"};
616
+ font-size: 15px;
502
617
  outline: none;
503
- transition: border-color 0.2s;
504
618
  box-sizing: border-box;
505
619
  margin: 0;
506
620
  }
507
621
 
508
622
  .pp-input:focus {
509
- border-color: ${primaryColor};
623
+ outline: none;
510
624
  }
511
625
 
512
626
  .pp-input::placeholder {
513
- color: ${colors.textSecondary};
627
+ color: ${isDark ? "#8696a0" : "#667781"};
514
628
  }
515
629
 
516
630
  .pp-send-btn {
517
- width: 40px;
518
- height: 40px;
519
- min-width: 40px;
631
+ width: 42px;
632
+ height: 42px;
633
+ min-width: 42px;
520
634
  border-radius: 50%;
521
- background: ${primaryColor};
635
+ background: #00a884;
522
636
  color: white;
523
637
  border: none;
524
638
  cursor: pointer;
525
639
  display: flex;
526
640
  align-items: center;
527
641
  justify-content: center;
528
- transition: opacity 0.2s, transform 0.1s;
642
+ transition: background 0.2s, transform 0.1s;
529
643
  flex-shrink: 0;
530
644
  margin: 0;
531
645
  padding: 0;
532
646
  }
533
647
 
534
648
  .pp-send-btn:not(:disabled):hover {
535
- transform: scale(1.05);
649
+ background: #008f72;
536
650
  }
537
651
 
538
652
  .pp-send-btn:not(:disabled):active {
@@ -540,27 +654,27 @@ function styles(primaryColor, theme) {
540
654
  }
541
655
 
542
656
  .pp-send-btn:disabled {
543
- opacity: 0.5;
657
+ background: ${isDark ? "#3b4a54" : "#b3b3b3"};
544
658
  cursor: not-allowed;
545
659
  }
546
660
 
547
661
  .pp-send-btn svg {
548
- width: 18px;
549
- height: 18px;
662
+ width: 20px;
663
+ height: 20px;
550
664
  }
551
665
 
552
666
  .pp-footer {
553
667
  text-align: center;
554
- padding: 8px;
555
- font-size: 11px;
556
- color: ${colors.textSecondary};
557
- border-top: 1px solid ${colors.border};
558
- opacity: 0.7;
668
+ padding: 6px 8px;
669
+ font-size: 10px;
670
+ color: ${isDark ? "#8696a0" : "#667781"};
671
+ background: ${resolvedFooterColor};
559
672
  }
560
673
 
561
674
  .pp-footer a {
562
- color: ${primaryColor};
675
+ color: ${isDark ? "#00a884" : "#008069"};
563
676
  text-decoration: none;
677
+ font-weight: 500;
564
678
  }
565
679
 
566
680
  .pp-footer a:hover {
@@ -582,26 +696,26 @@ function styles(primaryColor, theme) {
582
696
  }
583
697
 
584
698
  .pp-attach-btn {
585
- width: 40px;
586
- height: 40px;
587
- min-width: 40px;
699
+ width: 42px;
700
+ height: 42px;
701
+ min-width: 42px;
588
702
  border-radius: 50%;
589
703
  background: transparent;
590
- color: ${colors.textSecondary};
591
- border: 1px solid ${colors.border};
704
+ color: ${isDark ? "#8696a0" : "#54656f"};
705
+ border: none;
592
706
  cursor: pointer;
593
707
  display: flex;
594
708
  align-items: center;
595
709
  justify-content: center;
596
710
  margin: 0;
597
711
  padding: 0;
598
- transition: color 0.2s, border-color 0.2s;
712
+ transition: color 0.2s, background 0.2s;
599
713
  flex-shrink: 0;
600
714
  }
601
715
 
602
716
  .pp-attach-btn:hover:not(:disabled) {
603
- color: ${primaryColor};
604
- border-color: ${primaryColor};
717
+ color: ${isDark ? "#aebac1" : "#3b4a54"};
718
+ background: ${isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.05)"};
605
719
  }
606
720
 
607
721
  .pp-attach-btn:disabled {
@@ -610,28 +724,27 @@ function styles(primaryColor, theme) {
610
724
  }
611
725
 
612
726
  .pp-attach-btn svg {
613
- width: 18px;
614
- height: 18px;
727
+ width: 22px;
728
+ height: 22px;
615
729
  }
616
730
 
617
731
  .pp-attachments-preview {
618
732
  display: flex;
619
733
  gap: 8px;
620
- padding: 8px 12px;
621
- border-top: 1px solid ${colors.border};
734
+ padding: 10px 12px;
622
735
  overflow-x: auto;
623
- background: ${colors.bgSecondary};
736
+ background: ${resolvedFooterColor};
624
737
  }
625
738
 
626
739
  .pp-attachment-preview {
627
740
  position: relative;
628
- width: 60px;
629
- height: 60px;
630
- border-radius: 8px;
741
+ width: 64px;
742
+ height: 64px;
743
+ border-radius: 10px;
631
744
  overflow: hidden;
632
745
  flex-shrink: 0;
633
- background: ${colors.bg};
634
- border: 1px solid ${colors.border};
746
+ background: ${isDark ? "#2a3942" : "#ffffff"};
747
+ box-shadow: 0 1px 2px rgba(0,0,0,0.1);
635
748
  }
636
749
 
637
750
  .pp-preview-img {
@@ -715,7 +828,10 @@ function styles(primaryColor, theme) {
715
828
  display: flex;
716
829
  flex-direction: column;
717
830
  gap: 8px;
718
- margin-top: 4px;
831
+ margin-top: 6px;
832
+ max-width: 100%;
833
+ align-items: flex-start;
834
+ flex-shrink: 0;
719
835
  }
720
836
 
721
837
  .pp-attachment {
@@ -726,11 +842,22 @@ function styles(primaryColor, theme) {
726
842
  overflow: hidden;
727
843
  }
728
844
 
845
+ .pp-attachment-image,
846
+ .pp-attachment-video,
847
+ .pp-attachment-audio {
848
+ width: 240px;
849
+ max-width: 100%;
850
+ }
851
+
729
852
  .pp-attachment-image img {
730
- max-width: 200px;
853
+ width: 100% !important;
854
+ height: auto !important;
855
+ max-width: 240px;
731
856
  max-height: 200px;
732
857
  border-radius: 8px;
733
858
  display: block;
859
+ object-fit: cover !important;
860
+ object-position: center;
734
861
  }
735
862
 
736
863
  .pp-attachment-audio {
@@ -740,7 +867,8 @@ function styles(primaryColor, theme) {
740
867
  }
741
868
 
742
869
  .pp-attachment-audio audio {
743
- width: 200px;
870
+ width: 240px;
871
+ max-width: 100%;
744
872
  height: 36px;
745
873
  }
746
874
 
@@ -750,14 +878,18 @@ function styles(primaryColor, theme) {
750
878
  white-space: nowrap;
751
879
  overflow: hidden;
752
880
  text-overflow: ellipsis;
753
- max-width: 200px;
881
+ max-width: 100%;
754
882
  }
755
883
 
756
884
  .pp-attachment-video video {
757
- max-width: 200px;
758
- max-height: 200px;
885
+ width: 100% !important;
886
+ height: auto !important;
887
+ max-width: 240px;
888
+ max-height: none;
759
889
  border-radius: 8px;
760
890
  display: block;
891
+ object-fit: contain !important;
892
+ object-position: center;
761
893
  }
762
894
 
763
895
  .pp-attachment-file {
@@ -806,81 +938,86 @@ function styles(primaryColor, theme) {
806
938
  .pp-drop-overlay {
807
939
  position: absolute;
808
940
  inset: 0;
809
- background: ${isDark ? "rgba(0,0,0,0.9)" : "rgba(255,255,255,0.95)"};
941
+ background: ${isDark ? "rgba(17, 27, 33, 0.95)" : "rgba(255,255,255,0.97)"};
810
942
  display: flex;
811
943
  flex-direction: column;
812
944
  align-items: center;
813
945
  justify-content: center;
814
- gap: 12px;
946
+ gap: 16px;
815
947
  z-index: 100;
816
- border: 3px dashed ${primaryColor};
817
- border-radius: 16px;
948
+ border: 3px dashed #00a884;
949
+ border-radius: 12px;
818
950
  margin: 4px;
819
951
  pointer-events: none;
820
952
  }
821
953
 
822
954
  .pp-drop-icon svg {
823
- width: 48px;
824
- height: 48px;
825
- color: ${primaryColor};
955
+ width: 56px;
956
+ height: 56px;
957
+ color: #00a884;
826
958
  }
827
959
 
828
960
  .pp-drop-text {
829
- font-size: 16px;
961
+ font-size: 17px;
830
962
  font-weight: 500;
831
- color: ${colors.text};
963
+ color: ${isDark ? "#e9edef" : "#111b21"};
832
964
  }
833
965
 
834
966
  /* Message Context Menu */
835
967
  .pp-message-menu {
836
968
  position: fixed;
837
- background: ${colors.bg};
838
- border: 1px solid ${colors.border};
839
- border-radius: 8px;
840
- box-shadow: 0 4px 12px rgba(0,0,0,0.15);
841
- padding: 4px;
969
+ background: ${isDark ? "#233138" : "#ffffff"};
970
+ border: none;
971
+ border-radius: 12px;
972
+ box-shadow: 0 8px 24px rgba(0,0,0,0.2), 0 2px 8px rgba(0,0,0,0.1);
973
+ padding: 6px;
842
974
  z-index: 200;
843
- min-width: 120px;
975
+ min-width: 140px;
844
976
  }
845
977
 
846
978
  .pp-message-menu button {
847
979
  display: flex;
848
980
  align-items: center;
849
- gap: 8px;
981
+ gap: 10px;
850
982
  width: 100%;
851
- padding: 8px 12px;
983
+ padding: 10px 14px;
852
984
  border: none;
853
985
  background: transparent;
854
- color: ${colors.text};
855
- font-size: 13px;
986
+ color: ${isDark ? "#e9edef" : "#111b21"};
987
+ font-size: 14px;
856
988
  cursor: pointer;
857
- border-radius: 4px;
989
+ border-radius: 8px;
858
990
  text-align: left;
991
+ transition: background 0.15s;
859
992
  }
860
993
 
861
994
  .pp-message-menu button:hover {
862
- background: ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"};
995
+ background: ${isDark ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.05)"};
863
996
  }
864
997
 
865
998
  .pp-message-menu button svg {
866
- width: 16px;
867
- height: 16px;
999
+ width: 18px;
1000
+ height: 18px;
868
1001
  }
869
1002
 
870
1003
  .pp-menu-delete {
871
1004
  color: #ef4444 !important;
872
1005
  }
873
1006
 
1007
+ .pp-menu-delete:hover {
1008
+ background: ${isDark ? "rgba(239,68,68,0.15)" : "rgba(239,68,68,0.08)"} !important;
1009
+ }
1010
+
874
1011
  /* Edit Modal */
875
1012
  .pp-edit-modal {
876
1013
  position: absolute;
877
1014
  bottom: 80px;
878
1015
  left: 12px;
879
1016
  right: 12px;
880
- background: ${colors.bg};
881
- border: 1px solid ${colors.border};
1017
+ background: ${isDark ? "#233138" : "#ffffff"};
1018
+ border: none;
882
1019
  border-radius: 12px;
883
- box-shadow: 0 4px 20px rgba(0,0,0,0.15);
1020
+ box-shadow: 0 8px 28px rgba(0,0,0,0.25), 0 2px 8px rgba(0,0,0,0.1);
884
1021
  z-index: 150;
885
1022
  overflow: hidden;
886
1023
  }
@@ -889,17 +1026,24 @@ function styles(primaryColor, theme) {
889
1026
  display: flex;
890
1027
  justify-content: space-between;
891
1028
  align-items: center;
892
- padding: 12px 16px;
893
- border-bottom: 1px solid ${colors.border};
1029
+ padding: 14px 16px;
1030
+ border-bottom: 1px solid ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.08)"};
894
1031
  font-weight: 500;
1032
+ color: ${isDark ? "#e9edef" : "#111b21"};
895
1033
  }
896
1034
 
897
1035
  .pp-edit-header button {
898
1036
  background: transparent;
899
1037
  border: none;
900
- color: ${colors.textSecondary};
1038
+ color: ${isDark ? "#8696a0" : "#667781"};
901
1039
  cursor: pointer;
902
- padding: 4px;
1040
+ padding: 6px;
1041
+ border-radius: 50%;
1042
+ transition: background 0.15s;
1043
+ }
1044
+
1045
+ .pp-edit-header button:hover {
1046
+ background: ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"};
903
1047
  }
904
1048
 
905
1049
  .pp-edit-header button svg {
@@ -909,210 +1053,840 @@ function styles(primaryColor, theme) {
909
1053
 
910
1054
  .pp-edit-input {
911
1055
  width: 100%;
912
- padding: 12px 16px;
1056
+ padding: 14px 16px;
913
1057
  border: none;
914
1058
  background: transparent;
915
- color: ${colors.text};
916
- font-size: 14px;
1059
+ color: ${isDark ? "#e9edef" : "#111b21"};
1060
+ font-size: 15px;
917
1061
  resize: none;
918
1062
  min-height: 80px;
919
1063
  outline: none;
1064
+ line-height: 1.5;
1065
+ }
1066
+
1067
+ .pp-edit-input::placeholder {
1068
+ color: ${isDark ? "#8696a0" : "#667781"};
920
1069
  }
921
1070
 
922
1071
  .pp-edit-actions {
923
1072
  display: flex;
924
1073
  justify-content: flex-end;
925
- gap: 8px;
1074
+ gap: 10px;
926
1075
  padding: 12px 16px;
927
- border-top: 1px solid ${colors.border};
1076
+ border-top: 1px solid ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.08)"};
928
1077
  }
929
1078
 
930
1079
  .pp-edit-cancel {
931
- padding: 8px 16px;
932
- border: 1px solid ${colors.border};
933
- border-radius: 6px;
934
- background: transparent;
935
- color: ${colors.text};
936
- font-size: 13px;
1080
+ padding: 10px 20px;
1081
+ border: none;
1082
+ border-radius: 8px;
1083
+ background: ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"};
1084
+ color: ${isDark ? "#e9edef" : "#111b21"};
1085
+ font-size: 14px;
937
1086
  cursor: pointer;
1087
+ transition: background 0.15s;
1088
+ }
1089
+
1090
+ .pp-edit-cancel:hover {
1091
+ background: ${isDark ? "rgba(255,255,255,0.15)" : "rgba(0,0,0,0.08)"};
938
1092
  }
939
1093
 
940
1094
  .pp-edit-save {
941
- padding: 8px 16px;
1095
+ padding: 10px 20px;
942
1096
  border: none;
943
- border-radius: 6px;
944
- background: ${primaryColor};
1097
+ border-radius: 8px;
1098
+ background: #00a884;
945
1099
  color: white;
1100
+ font-size: 14px;
1101
+ font-weight: 500;
1102
+ cursor: pointer;
1103
+ transition: background 0.15s;
1104
+ }
1105
+
1106
+ .pp-edit-save:hover:not(:disabled) {
1107
+ background: #008f72;
1108
+ }
1109
+
1110
+ .pp-edit-save:disabled {
1111
+ background: ${isDark ? "#3b4a54" : "#b3b3b3"};
1112
+ cursor: not-allowed;
1113
+ }
1114
+
1115
+ /* Reply Preview */
1116
+ .pp-reply-preview {
1117
+ display: flex;
1118
+ align-items: center;
1119
+ gap: 10px;
1120
+ padding: 8px 12px;
1121
+ background: ${resolvedFooterColor};
1122
+ border-left: 4px solid #00a884;
1123
+ }
1124
+
1125
+ .pp-reply-preview-content {
1126
+ flex: 1;
1127
+ min-width: 0;
1128
+ }
1129
+
1130
+ .pp-reply-label {
1131
+ display: block;
1132
+ font-size: 12px;
1133
+ color: #00a884;
1134
+ font-weight: 500;
1135
+ margin-bottom: 2px;
1136
+ }
1137
+
1138
+ .pp-reply-text {
1139
+ display: block;
1140
+ font-size: 13px;
1141
+ color: ${isDark ? "#8696a0" : "#667781"};
1142
+ white-space: nowrap;
1143
+ overflow: hidden;
1144
+ text-overflow: ellipsis;
1145
+ }
1146
+
1147
+ .pp-reply-cancel {
1148
+ background: transparent;
1149
+ border: none;
1150
+ border-radius: 50%;
1151
+ color: ${isDark ? "#8696a0" : "#667781"};
1152
+ cursor: pointer;
1153
+ padding: 0;
1154
+ width: 28px;
1155
+ height: 28px;
1156
+ min-width: 28px;
1157
+ display: flex;
1158
+ align-items: center;
1159
+ justify-content: center;
1160
+ flex-shrink: 0;
1161
+ transition: background 0.15s, color 0.15s;
1162
+ }
1163
+
1164
+ .pp-reply-cancel:hover {
1165
+ background: ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.08)"};
1166
+ color: ${isDark ? "#aebac1" : "#3b4a54"};
1167
+ }
1168
+
1169
+ .pp-reply-cancel svg {
1170
+ width: 16px;
1171
+ height: 16px;
1172
+ }
1173
+
1174
+ /* Reply Quote in Message */
1175
+ .pp-reply-quote {
1176
+ background: ${isDark ? "rgba(0,0,0,0.2)" : "rgba(0,0,0,0.05)"};
1177
+ border-left: 3px solid #00a884;
1178
+ padding: 6px 10px;
1179
+ margin-bottom: 4px;
1180
+ border-radius: 0 6px 6px 0;
1181
+ font-size: 13px;
1182
+ position: relative;
1183
+ z-index: 1;
1184
+ }
1185
+
1186
+ .pp-reply-sender {
1187
+ display: block;
1188
+ font-weight: 500;
1189
+ color: #00a884;
1190
+ margin-bottom: 2px;
1191
+ font-size: 12px;
1192
+ }
1193
+
1194
+ .pp-reply-content {
1195
+ display: block;
1196
+ color: ${isDark ? "#8696a0" : "#667781"};
1197
+ white-space: nowrap;
1198
+ overflow: hidden;
1199
+ text-overflow: ellipsis;
1200
+ }
1201
+
1202
+ /* Clickable reply quote */
1203
+ .pp-reply-quote-clickable {
1204
+ cursor: pointer;
1205
+ transition: background 0.15s;
1206
+ }
1207
+
1208
+ .pp-reply-quote-clickable:hover {
1209
+ background: ${isDark ? "rgba(0,0,0,0.3)" : "rgba(0,0,0,0.08)"};
1210
+ }
1211
+
1212
+ .pp-reply-quote-clickable:active {
1213
+ transform: scale(0.99);
1214
+ }
1215
+
1216
+ /* Reply quote in visitor message bubble needs higher contrast */
1217
+ .pp-message-visitor .pp-reply-quote {
1218
+ background: ${isDark ? "rgba(0,0,0,0.2)" : "rgba(0,0,0,0.08)"};
1219
+ border-left-color: ${isDark ? "rgba(255,255,255,0.5)" : "#00a884"};
1220
+ }
1221
+
1222
+ .pp-message-visitor .pp-reply-quote-clickable:hover {
1223
+ background: ${isDark ? "rgba(0,0,0,0.3)" : "rgba(0,0,0,0.12)"};
1224
+ }
1225
+
1226
+ .pp-message-visitor .pp-reply-sender {
1227
+ color: ${isDark ? "rgba(255,255,255,0.9)" : "#00a884"};
1228
+ }
1229
+
1230
+ .pp-message-visitor .pp-reply-content {
1231
+ color: ${isDark ? "rgba(255,255,255,0.7)" : "rgba(0,0,0,0.6)"};
1232
+ }
1233
+
1234
+ /* Message highlight animation (when scrolling to a message) */
1235
+ .pp-message-highlight {
1236
+ animation: pp-highlight-pulse 1.5s ease-out;
1237
+ }
1238
+
1239
+ @keyframes pp-highlight-pulse {
1240
+ 0% {
1241
+ box-shadow: 0 0 0 0 rgba(0, 168, 132, 0.5);
1242
+ }
1243
+ 30% {
1244
+ box-shadow: 0 0 0 6px rgba(0, 168, 132, 0.25);
1245
+ }
1246
+ 100% {
1247
+ box-shadow: 0 0 0 0 rgba(0, 168, 132, 0);
1248
+ }
1249
+ }
1250
+
1251
+ /* Deleted Message */
1252
+ .pp-message-deleted {
1253
+ opacity: 0.6;
1254
+ }
1255
+
1256
+ .pp-deleted-content {
1257
+ font-style: italic;
1258
+ color: ${colors.textSecondary};
1259
+ display: flex;
1260
+ align-items: center;
1261
+ gap: 4px;
1262
+ }
1263
+
1264
+ .pp-deleted-icon {
1265
+ font-size: 12px;
1266
+ }
1267
+
1268
+ /* Edited Badge */
1269
+ .pp-edited-badge {
1270
+ font-size: 10px;
1271
+ margin-left: 4px;
1272
+ font-style: italic;
1273
+ opacity: 0.7;
1274
+ }
1275
+
1276
+ /* Pre-Chat Form */
1277
+ .pp-prechat {
1278
+ flex: 1;
1279
+ display: flex;
1280
+ flex-direction: column;
1281
+ padding: 24px 20px;
1282
+ overflow-y: auto;
1283
+ background: ${isDark ? "#111b21" : "#ffffff"};
1284
+ }
1285
+
1286
+ .pp-prechat-title {
1287
+ font-size: 20px;
1288
+ font-weight: 600;
1289
+ margin-bottom: 8px;
1290
+ color: ${isDark ? "#e9edef" : "#111b21"};
1291
+ }
1292
+
1293
+ .pp-prechat-subtitle {
1294
+ font-size: 14px;
1295
+ color: ${isDark ? "#8696a0" : "#667781"};
1296
+ margin-bottom: 24px;
1297
+ line-height: 1.5;
1298
+ }
1299
+
1300
+ .pp-prechat-tabs {
1301
+ display: flex;
1302
+ gap: 8px;
1303
+ margin-bottom: 20px;
1304
+ }
1305
+
1306
+ .pp-prechat-tab {
1307
+ flex: 1;
1308
+ padding: 10px;
1309
+ border: 1px solid ${colors.border};
1310
+ border-radius: 8px;
1311
+ background: transparent;
1312
+ color: ${colors.textSecondary};
1313
+ font-size: 13px;
1314
+ cursor: pointer;
1315
+ transition: all 0.2s;
1316
+ display: flex;
1317
+ align-items: center;
1318
+ justify-content: center;
1319
+ gap: 6px;
1320
+ }
1321
+
1322
+ .pp-prechat-tab:hover {
1323
+ background: ${colors.bgSecondary};
1324
+ }
1325
+
1326
+ .pp-prechat-tab.active {
1327
+ background: ${primaryColor}15;
1328
+ border-color: ${primaryColor};
1329
+ color: ${primaryColor};
1330
+ }
1331
+
1332
+ .pp-prechat-tab svg {
1333
+ width: 16px;
1334
+ height: 16px;
1335
+ }
1336
+
1337
+ .pp-prechat-field {
1338
+ margin-bottom: 16px;
1339
+ }
1340
+
1341
+ .pp-prechat-label {
1342
+ display: block;
1343
+ font-size: 12px;
1344
+ font-weight: 500;
1345
+ color: ${colors.textSecondary};
1346
+ margin-bottom: 6px;
1347
+ }
1348
+
1349
+ .pp-prechat-input {
1350
+ width: 100%;
1351
+ height: 44px;
1352
+ padding: 0 14px;
1353
+ border: 1px solid ${colors.border};
1354
+ border-radius: 8px;
1355
+ background: ${colors.bg};
1356
+ color: ${colors.text};
1357
+ font-size: 14px;
1358
+ outline: none;
1359
+ transition: border-color 0.2s;
1360
+ box-sizing: border-box;
1361
+ }
1362
+
1363
+ .pp-prechat-input:focus {
1364
+ border-color: ${primaryColor};
1365
+ }
1366
+
1367
+ .pp-prechat-input::placeholder {
1368
+ color: ${colors.textSecondary};
1369
+ }
1370
+
1371
+ .pp-prechat-input.error {
1372
+ border-color: #ef4444;
1373
+ }
1374
+
1375
+ .pp-prechat-error {
1376
+ color: #ef4444;
1377
+ font-size: 12px;
1378
+ margin-top: 4px;
1379
+ }
1380
+
1381
+ .pp-phone-input-wrapper {
1382
+ display: flex;
1383
+ gap: 8px;
1384
+ }
1385
+
1386
+ .pp-country-select {
1387
+ position: relative;
1388
+ }
1389
+
1390
+ .pp-country-btn {
1391
+ display: flex;
1392
+ align-items: center;
1393
+ gap: 6px;
1394
+ height: 44px;
1395
+ padding: 0 10px;
1396
+ border: 1px solid ${colors.border};
1397
+ border-radius: 8px;
1398
+ background: ${colors.bg};
1399
+ color: ${colors.text};
1400
+ font-size: 14px;
1401
+ cursor: pointer;
1402
+ transition: border-color 0.2s;
1403
+ }
1404
+
1405
+ .pp-country-btn:focus {
1406
+ border-color: ${primaryColor};
1407
+ outline: none;
1408
+ }
1409
+
1410
+ .pp-country-flag {
1411
+ font-size: 18px;
1412
+ line-height: 1;
1413
+ }
1414
+
1415
+ .pp-country-code {
946
1416
  font-size: 13px;
947
- cursor: pointer;
1417
+ color: ${colors.textSecondary};
948
1418
  }
949
1419
 
950
- .pp-edit-save:disabled {
951
- opacity: 0.5;
952
- cursor: not-allowed;
1420
+ .pp-country-chevron {
1421
+ width: 12px;
1422
+ height: 12px;
1423
+ color: ${colors.textSecondary};
953
1424
  }
954
1425
 
955
- /* Reply Preview */
956
- .pp-reply-preview {
957
- display: flex;
958
- align-items: center;
959
- gap: 8px;
960
- padding: 8px 12px;
961
- background: ${isDark ? "rgba(255,255,255,0.05)" : "rgba(0,0,0,0.03)"};
962
- border-top: 1px solid ${colors.border};
963
- border-left: 3px solid ${primaryColor};
1426
+ .pp-country-dropdown {
1427
+ position: absolute;
1428
+ top: calc(100% + 4px);
1429
+ left: 0;
1430
+ width: 280px;
1431
+ max-height: 280px;
1432
+ overflow-y: auto;
1433
+ background: ${colors.bg};
1434
+ border: 1px solid ${colors.border};
1435
+ border-radius: 8px;
1436
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
1437
+ z-index: 100;
964
1438
  }
965
1439
 
966
- .pp-reply-preview-content {
967
- flex: 1;
968
- min-width: 0;
1440
+ .pp-country-search {
1441
+ position: sticky;
1442
+ top: 0;
1443
+ padding: 8px;
1444
+ background: ${colors.bg};
1445
+ border-bottom: 1px solid ${colors.border};
969
1446
  }
970
1447
 
971
- .pp-reply-label {
972
- display: block;
973
- font-size: 11px;
974
- color: ${primaryColor};
975
- font-weight: 500;
976
- margin-bottom: 2px;
1448
+ .pp-country-search-input {
1449
+ width: 100%;
1450
+ height: 36px;
1451
+ padding: 0 12px;
1452
+ border: 1px solid ${colors.border};
1453
+ border-radius: 6px;
1454
+ background: ${colors.bgSecondary};
1455
+ color: ${colors.text};
1456
+ font-size: 13px;
1457
+ outline: none;
1458
+ box-sizing: border-box;
977
1459
  }
978
1460
 
979
- .pp-reply-text {
980
- display: block;
981
- font-size: 12px;
982
- color: ${colors.textSecondary};
983
- white-space: nowrap;
984
- overflow: hidden;
985
- text-overflow: ellipsis;
1461
+ .pp-country-search-input:focus {
1462
+ border-color: ${primaryColor};
986
1463
  }
987
1464
 
988
- .pp-reply-cancel {
989
- background: ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"};
990
- border: none;
991
- border-radius: 50%;
992
- color: ${colors.textSecondary};
993
- cursor: pointer;
994
- padding: 0;
995
- width: 24px;
996
- height: 24px;
997
- min-width: 24px;
1465
+ .pp-country-list {
1466
+ padding: 4px;
1467
+ }
1468
+
1469
+ .pp-country-option {
998
1470
  display: flex;
999
1471
  align-items: center;
1000
- justify-content: center;
1001
- flex-shrink: 0;
1472
+ gap: 10px;
1473
+ padding: 10px 12px;
1474
+ cursor: pointer;
1475
+ border-radius: 6px;
1002
1476
  transition: background 0.15s;
1003
1477
  }
1004
1478
 
1005
- .pp-reply-cancel:hover {
1006
- background: ${isDark ? "rgba(255,255,255,0.2)" : "rgba(0,0,0,0.1)"};
1479
+ .pp-country-option:hover {
1480
+ background: ${colors.bgSecondary};
1007
1481
  }
1008
1482
 
1009
- .pp-reply-cancel svg {
1010
- width: 14px;
1011
- height: 14px;
1483
+ .pp-country-option.selected {
1484
+ background: ${primaryColor}15;
1012
1485
  }
1013
1486
 
1014
- /* Reply Quote in Message */
1015
- .pp-reply-quote {
1016
- background: ${isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.05)"};
1017
- border-left: 2px solid ${primaryColor};
1018
- padding: 4px 8px;
1019
- margin-bottom: 6px;
1020
- border-radius: 0 4px 4px 0;
1021
- font-size: 12px;
1022
- position: relative;
1023
- z-index: 1;
1487
+ .pp-country-name {
1488
+ flex: 1;
1489
+ font-size: 13px;
1490
+ color: ${colors.text};
1024
1491
  }
1025
1492
 
1026
- .pp-reply-sender {
1027
- display: block;
1028
- font-weight: 500;
1029
- color: ${primaryColor};
1030
- margin-bottom: 2px;
1493
+ .pp-country-dial {
1494
+ font-size: 12px;
1495
+ color: ${colors.textSecondary};
1031
1496
  }
1032
1497
 
1033
- .pp-reply-content {
1034
- display: block;
1035
- color: ${colors.textSecondary};
1036
- white-space: nowrap;
1037
- overflow: hidden;
1038
- text-overflow: ellipsis;
1498
+ .pp-phone-number-input {
1499
+ flex: 1;
1039
1500
  }
1040
1501
 
1041
- /* Clickable reply quote */
1042
- .pp-reply-quote-clickable {
1502
+ .pp-prechat-submit {
1503
+ width: 100%;
1504
+ height: 48px;
1505
+ margin-top: 12px;
1506
+ border: none;
1507
+ border-radius: 8px;
1508
+ background: #00a884;
1509
+ color: white;
1510
+ font-size: 15px;
1511
+ font-weight: 500;
1043
1512
  cursor: pointer;
1044
- transition: background 0.15s, transform 0.1s;
1513
+ transition: background 0.2s, transform 0.1s;
1045
1514
  }
1046
1515
 
1047
- .pp-reply-quote-clickable:hover {
1048
- background: ${isDark ? "rgba(255,255,255,0.15)" : "rgba(0,0,0,0.08)"};
1516
+ .pp-prechat-submit:hover:not(:disabled) {
1517
+ background: #008f72;
1049
1518
  }
1050
1519
 
1051
- .pp-reply-quote-clickable:active {
1520
+ .pp-prechat-submit:active:not(:disabled) {
1052
1521
  transform: scale(0.98);
1053
1522
  }
1054
1523
 
1055
- /* Reply quote in visitor message bubble needs higher contrast */
1056
- .pp-message-visitor .pp-reply-quote {
1057
- background: rgba(255, 255, 255, 0.18);
1058
- border-left-color: rgba(255, 255, 255, 0.7);
1524
+ .pp-prechat-submit:disabled {
1525
+ background: ${isDark ? "#3b4a54" : "#b3b3b3"};
1526
+ cursor: not-allowed;
1059
1527
  }
1060
1528
 
1061
- .pp-message-visitor .pp-reply-quote-clickable:hover {
1062
- background: rgba(255, 255, 255, 0.25);
1529
+ .pp-prechat-skip {
1530
+ width: 100%;
1531
+ padding: 14px;
1532
+ margin-top: 8px;
1533
+ border: none;
1534
+ background: transparent;
1535
+ color: ${isDark ? "#8696a0" : "#667781"};
1536
+ font-size: 14px;
1537
+ cursor: pointer;
1538
+ transition: color 0.2s;
1063
1539
  }
1064
1540
 
1065
- .pp-message-visitor .pp-reply-sender,
1066
- .pp-message-visitor .pp-reply-content {
1067
- color: rgba(255, 255, 255, 0.9);
1541
+ .pp-prechat-skip:hover {
1542
+ color: ${isDark ? "#aebac1" : "#3b4a54"};
1068
1543
  }
1544
+ `;
1545
+ }
1069
1546
 
1070
- /* Message highlight animation (when scrolling to a message) */
1071
- .pp-message-highlight {
1072
- animation: pp-highlight-pulse 1.5s ease-out;
1073
- }
1547
+ // src/components/PreChatForm.tsx
1548
+ var import_hooks = require("preact/hooks");
1549
+ var import_min = require("libphonenumber-js/min");
1550
+
1551
+ // src/data/countries.ts
1552
+ var countries = [
1553
+ // Europe
1554
+ { code: "FR", name: "France", dialCode: "+33", flag: "\u{1F1EB}\u{1F1F7}" },
1555
+ { code: "DE", name: "Germany", dialCode: "+49", flag: "\u{1F1E9}\u{1F1EA}" },
1556
+ { code: "GB", name: "United Kingdom", dialCode: "+44", flag: "\u{1F1EC}\u{1F1E7}" },
1557
+ { code: "ES", name: "Spain", dialCode: "+34", flag: "\u{1F1EA}\u{1F1F8}" },
1558
+ { code: "IT", name: "Italy", dialCode: "+39", flag: "\u{1F1EE}\u{1F1F9}" },
1559
+ { code: "PT", name: "Portugal", dialCode: "+351", flag: "\u{1F1F5}\u{1F1F9}" },
1560
+ { code: "NL", name: "Netherlands", dialCode: "+31", flag: "\u{1F1F3}\u{1F1F1}" },
1561
+ { code: "BE", name: "Belgium", dialCode: "+32", flag: "\u{1F1E7}\u{1F1EA}" },
1562
+ { code: "CH", name: "Switzerland", dialCode: "+41", flag: "\u{1F1E8}\u{1F1ED}" },
1563
+ { code: "AT", name: "Austria", dialCode: "+43", flag: "\u{1F1E6}\u{1F1F9}" },
1564
+ { code: "SE", name: "Sweden", dialCode: "+46", flag: "\u{1F1F8}\u{1F1EA}" },
1565
+ { code: "NO", name: "Norway", dialCode: "+47", flag: "\u{1F1F3}\u{1F1F4}" },
1566
+ { code: "DK", name: "Denmark", dialCode: "+45", flag: "\u{1F1E9}\u{1F1F0}" },
1567
+ { code: "FI", name: "Finland", dialCode: "+358", flag: "\u{1F1EB}\u{1F1EE}" },
1568
+ { code: "PL", name: "Poland", dialCode: "+48", flag: "\u{1F1F5}\u{1F1F1}" },
1569
+ { code: "CZ", name: "Czech Republic", dialCode: "+420", flag: "\u{1F1E8}\u{1F1FF}" },
1570
+ { code: "GR", name: "Greece", dialCode: "+30", flag: "\u{1F1EC}\u{1F1F7}" },
1571
+ { code: "IE", name: "Ireland", dialCode: "+353", flag: "\u{1F1EE}\u{1F1EA}" },
1572
+ { code: "RO", name: "Romania", dialCode: "+40", flag: "\u{1F1F7}\u{1F1F4}" },
1573
+ { code: "HU", name: "Hungary", dialCode: "+36", flag: "\u{1F1ED}\u{1F1FA}" },
1574
+ // North America
1575
+ { code: "US", name: "United States", dialCode: "+1", flag: "\u{1F1FA}\u{1F1F8}" },
1576
+ { code: "CA", name: "Canada", dialCode: "+1", flag: "\u{1F1E8}\u{1F1E6}" },
1577
+ { code: "MX", name: "Mexico", dialCode: "+52", flag: "\u{1F1F2}\u{1F1FD}" },
1578
+ // South America
1579
+ { code: "BR", name: "Brazil", dialCode: "+55", flag: "\u{1F1E7}\u{1F1F7}" },
1580
+ { code: "AR", name: "Argentina", dialCode: "+54", flag: "\u{1F1E6}\u{1F1F7}" },
1581
+ { code: "CL", name: "Chile", dialCode: "+56", flag: "\u{1F1E8}\u{1F1F1}" },
1582
+ { code: "CO", name: "Colombia", dialCode: "+57", flag: "\u{1F1E8}\u{1F1F4}" },
1583
+ { code: "PE", name: "Peru", dialCode: "+51", flag: "\u{1F1F5}\u{1F1EA}" },
1584
+ // Asia
1585
+ { code: "CN", name: "China", dialCode: "+86", flag: "\u{1F1E8}\u{1F1F3}" },
1586
+ { code: "JP", name: "Japan", dialCode: "+81", flag: "\u{1F1EF}\u{1F1F5}" },
1587
+ { code: "KR", name: "South Korea", dialCode: "+82", flag: "\u{1F1F0}\u{1F1F7}" },
1588
+ { code: "IN", name: "India", dialCode: "+91", flag: "\u{1F1EE}\u{1F1F3}" },
1589
+ { code: "ID", name: "Indonesia", dialCode: "+62", flag: "\u{1F1EE}\u{1F1E9}" },
1590
+ { code: "TH", name: "Thailand", dialCode: "+66", flag: "\u{1F1F9}\u{1F1ED}" },
1591
+ { code: "VN", name: "Vietnam", dialCode: "+84", flag: "\u{1F1FB}\u{1F1F3}" },
1592
+ { code: "MY", name: "Malaysia", dialCode: "+60", flag: "\u{1F1F2}\u{1F1FE}" },
1593
+ { code: "SG", name: "Singapore", dialCode: "+65", flag: "\u{1F1F8}\u{1F1EC}" },
1594
+ { code: "PH", name: "Philippines", dialCode: "+63", flag: "\u{1F1F5}\u{1F1ED}" },
1595
+ { code: "PK", name: "Pakistan", dialCode: "+92", flag: "\u{1F1F5}\u{1F1F0}" },
1596
+ { code: "BD", name: "Bangladesh", dialCode: "+880", flag: "\u{1F1E7}\u{1F1E9}" },
1597
+ // Middle East
1598
+ { code: "AE", name: "United Arab Emirates", dialCode: "+971", flag: "\u{1F1E6}\u{1F1EA}" },
1599
+ { code: "SA", name: "Saudi Arabia", dialCode: "+966", flag: "\u{1F1F8}\u{1F1E6}" },
1600
+ { code: "IL", name: "Israel", dialCode: "+972", flag: "\u{1F1EE}\u{1F1F1}" },
1601
+ { code: "TR", name: "Turkey", dialCode: "+90", flag: "\u{1F1F9}\u{1F1F7}" },
1602
+ { code: "EG", name: "Egypt", dialCode: "+20", flag: "\u{1F1EA}\u{1F1EC}" },
1603
+ // Africa
1604
+ { code: "ZA", name: "South Africa", dialCode: "+27", flag: "\u{1F1FF}\u{1F1E6}" },
1605
+ { code: "NG", name: "Nigeria", dialCode: "+234", flag: "\u{1F1F3}\u{1F1EC}" },
1606
+ { code: "KE", name: "Kenya", dialCode: "+254", flag: "\u{1F1F0}\u{1F1EA}" },
1607
+ { code: "MA", name: "Morocco", dialCode: "+212", flag: "\u{1F1F2}\u{1F1E6}" },
1608
+ { code: "TN", name: "Tunisia", dialCode: "+216", flag: "\u{1F1F9}\u{1F1F3}" },
1609
+ { code: "DZ", name: "Algeria", dialCode: "+213", flag: "\u{1F1E9}\u{1F1FF}" },
1610
+ // Oceania
1611
+ { code: "AU", name: "Australia", dialCode: "+61", flag: "\u{1F1E6}\u{1F1FA}" },
1612
+ { code: "NZ", name: "New Zealand", dialCode: "+64", flag: "\u{1F1F3}\u{1F1FF}" },
1613
+ // Russia & CIS
1614
+ { code: "RU", name: "Russia", dialCode: "+7", flag: "\u{1F1F7}\u{1F1FA}" },
1615
+ { code: "UA", name: "Ukraine", dialCode: "+380", flag: "\u{1F1FA}\u{1F1E6}" }
1616
+ ].sort((a, b) => a.name.localeCompare(b.name));
1617
+ function findCountryByCode(code) {
1618
+ return countries.find((c) => c.code === code.toUpperCase());
1619
+ }
1620
+ var defaultCountry = findCountryByCode("FR");
1074
1621
 
1075
- @keyframes pp-highlight-pulse {
1076
- 0% {
1077
- box-shadow: 0 0 0 0 ${primaryColor}80;
1078
- }
1079
- 30% {
1080
- box-shadow: 0 0 0 6px ${primaryColor}40;
1622
+ // src/components/PreChatForm.tsx
1623
+ var import_jsx_runtime = require("preact/jsx-runtime");
1624
+ var EmailIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1625
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" }),
1626
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M22 7l-10 7L2 7" })
1627
+ ] });
1628
+ var PhoneIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime.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" }) });
1629
+ var ChevronIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6 9l6 6 6-6" }) });
1630
+ function isValidEmail(email) {
1631
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
1632
+ }
1633
+ function PreChatForm({ client: client2, config, onComplete, onSkip }) {
1634
+ const showEmailOnly = config.fields === "email-only";
1635
+ const showPhoneOnly = config.fields === "phone-only";
1636
+ const showBoth = config.fields === "email-and-phone";
1637
+ const showChoice = config.fields === "email-or-phone";
1638
+ const getDefaultTab = () => {
1639
+ if (showPhoneOnly) return "phone";
1640
+ return "email";
1641
+ };
1642
+ const [activeTab, setActiveTab] = (0, import_hooks.useState)(getDefaultTab());
1643
+ const [email, setEmail] = (0, import_hooks.useState)("");
1644
+ const [phone, setPhone] = (0, import_hooks.useState)("");
1645
+ const [selectedCountry, setSelectedCountry] = (0, import_hooks.useState)(defaultCountry);
1646
+ const [isCountryDropdownOpen, setIsCountryDropdownOpen] = (0, import_hooks.useState)(false);
1647
+ const [countrySearch, setCountrySearch] = (0, import_hooks.useState)("");
1648
+ const [emailError, setEmailError] = (0, import_hooks.useState)("");
1649
+ const [phoneError, setPhoneError] = (0, import_hooks.useState)("");
1650
+ const [isSubmitting, setIsSubmitting] = (0, import_hooks.useState)(false);
1651
+ const countryDropdownRef = (0, import_hooks.useRef)(null);
1652
+ const searchInputRef = (0, import_hooks.useRef)(null);
1653
+ (0, import_hooks.useEffect)(() => {
1654
+ const handleClickOutside = (e) => {
1655
+ if (countryDropdownRef.current && !countryDropdownRef.current.contains(e.target)) {
1656
+ setIsCountryDropdownOpen(false);
1081
1657
  }
1082
- 100% {
1083
- box-shadow: 0 0 0 0 ${primaryColor}00;
1658
+ };
1659
+ document.addEventListener("mousedown", handleClickOutside);
1660
+ return () => document.removeEventListener("mousedown", handleClickOutside);
1661
+ }, []);
1662
+ (0, import_hooks.useEffect)(() => {
1663
+ if (isCountryDropdownOpen && searchInputRef.current) {
1664
+ searchInputRef.current.focus();
1665
+ }
1666
+ }, [isCountryDropdownOpen]);
1667
+ const filteredCountries = countries.filter(
1668
+ (c) => c.name.toLowerCase().includes(countrySearch.toLowerCase()) || c.dialCode.includes(countrySearch) || c.code.toLowerCase().includes(countrySearch.toLowerCase())
1669
+ );
1670
+ const handleCountrySelect = (country) => {
1671
+ setSelectedCountry(country);
1672
+ setIsCountryDropdownOpen(false);
1673
+ setCountrySearch("");
1674
+ };
1675
+ const formatPhoneForDisplay = (value) => {
1676
+ const digits = value.replace(/\D/g, "");
1677
+ return digits;
1678
+ };
1679
+ const handlePhoneChange = (e) => {
1680
+ const target = e.target;
1681
+ const formatted = formatPhoneForDisplay(target.value);
1682
+ setPhone(formatted);
1683
+ setPhoneError("");
1684
+ };
1685
+ const getFullPhoneNumber = () => {
1686
+ if (!phone) return "";
1687
+ return `${selectedCountry.dialCode}${phone}`;
1688
+ };
1689
+ const validateForm = () => {
1690
+ let valid = true;
1691
+ if (showEmailOnly || showBoth) {
1692
+ if (!email.trim()) {
1693
+ setEmailError("Email is required");
1694
+ valid = false;
1695
+ } else if (!isValidEmail(email)) {
1696
+ setEmailError("Please enter a valid email");
1697
+ valid = false;
1084
1698
  }
1085
1699
  }
1086
-
1087
- /* Deleted Message */
1088
- .pp-message-deleted {
1089
- opacity: 0.6;
1090
- }
1091
-
1092
- .pp-deleted-content {
1093
- font-style: italic;
1094
- color: ${colors.textSecondary};
1095
- display: flex;
1096
- align-items: center;
1097
- gap: 4px;
1700
+ if (showPhoneOnly || showBoth) {
1701
+ const fullPhone = getFullPhoneNumber();
1702
+ if (!phone.trim()) {
1703
+ setPhoneError("Phone number is required");
1704
+ valid = false;
1705
+ } else if (!(0, import_min.isValidPhoneNumber)(fullPhone, selectedCountry.code)) {
1706
+ setPhoneError("Please enter a valid phone number");
1707
+ valid = false;
1708
+ }
1098
1709
  }
1099
-
1100
- .pp-deleted-icon {
1101
- font-size: 12px;
1710
+ if (showChoice) {
1711
+ if (activeTab === "email") {
1712
+ if (!email.trim()) {
1713
+ setEmailError("Email is required");
1714
+ valid = false;
1715
+ } else if (!isValidEmail(email)) {
1716
+ setEmailError("Please enter a valid email");
1717
+ valid = false;
1718
+ }
1719
+ } else {
1720
+ const fullPhone = getFullPhoneNumber();
1721
+ if (!phone.trim()) {
1722
+ setPhoneError("Phone number is required");
1723
+ valid = false;
1724
+ } else if (!(0, import_min.isValidPhoneNumber)(fullPhone, selectedCountry.code)) {
1725
+ setPhoneError("Please enter a valid phone number");
1726
+ valid = false;
1727
+ }
1728
+ }
1102
1729
  }
1103
-
1104
- /* Edited Badge */
1105
- .pp-edited-badge {
1106
- font-size: 10px;
1107
- color: ${colors.textSecondary};
1108
- margin-left: 4px;
1109
- font-style: italic;
1730
+ return valid;
1731
+ };
1732
+ const handleSubmit = async (e) => {
1733
+ e.preventDefault();
1734
+ if (!validateForm()) return;
1735
+ setIsSubmitting(true);
1736
+ try {
1737
+ const data = {};
1738
+ if (showEmailOnly || showBoth || showChoice && activeTab === "email") {
1739
+ data.email = email.trim();
1740
+ }
1741
+ if (showPhoneOnly || showBoth || showChoice && activeTab === "phone") {
1742
+ const fullPhone = getFullPhoneNumber();
1743
+ const parsed = (0, import_min.parsePhoneNumber)(fullPhone, selectedCountry.code);
1744
+ if (parsed) {
1745
+ data.phone = parsed.format("E.164");
1746
+ data.phoneCountry = selectedCountry.code;
1747
+ }
1748
+ }
1749
+ await client2.submitPreChat(data);
1750
+ onComplete();
1751
+ } catch (err) {
1752
+ console.error("[PreChatForm] Submit error:", err);
1753
+ if (activeTab === "email" || showEmailOnly || showBoth) {
1754
+ setEmailError("Something went wrong. Please try again.");
1755
+ } else {
1756
+ setPhoneError("Something went wrong. Please try again.");
1757
+ }
1758
+ } finally {
1759
+ setIsSubmitting(false);
1110
1760
  }
1111
- `;
1761
+ };
1762
+ const renderEmailField = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-prechat-field", children: [
1763
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { class: "pp-prechat-label", children: "Email address" }),
1764
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1765
+ "input",
1766
+ {
1767
+ type: "email",
1768
+ class: `pp-prechat-input ${emailError ? "error" : ""}`,
1769
+ placeholder: "you@example.com",
1770
+ value: email,
1771
+ onInput: (e) => {
1772
+ setEmail(e.target.value);
1773
+ setEmailError("");
1774
+ }
1775
+ }
1776
+ ),
1777
+ emailError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-prechat-error", children: emailError })
1778
+ ] });
1779
+ const renderPhoneField = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-prechat-field", children: [
1780
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { class: "pp-prechat-label", children: "Phone number" }),
1781
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-phone-input-wrapper", children: [
1782
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-country-select", ref: countryDropdownRef, children: [
1783
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1784
+ "button",
1785
+ {
1786
+ type: "button",
1787
+ class: "pp-country-btn",
1788
+ onClick: () => setIsCountryDropdownOpen(!isCountryDropdownOpen),
1789
+ children: [
1790
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-country-flag", children: selectedCountry.flag }),
1791
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-country-code", children: selectedCountry.dialCode }),
1792
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronIcon, {})
1793
+ ]
1794
+ }
1795
+ ),
1796
+ isCountryDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-country-dropdown", children: [
1797
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-country-search", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1798
+ "input",
1799
+ {
1800
+ ref: searchInputRef,
1801
+ type: "text",
1802
+ class: "pp-country-search-input",
1803
+ placeholder: "Search country...",
1804
+ value: countrySearch,
1805
+ onInput: (e) => setCountrySearch(e.target.value)
1806
+ }
1807
+ ) }),
1808
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-country-list", children: filteredCountries.map((country) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1809
+ "div",
1810
+ {
1811
+ class: `pp-country-option ${country.code === selectedCountry.code ? "selected" : ""}`,
1812
+ onClick: () => handleCountrySelect(country),
1813
+ children: [
1814
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-country-flag", children: country.flag }),
1815
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-country-name", children: country.name }),
1816
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-country-dial", children: country.dialCode })
1817
+ ]
1818
+ },
1819
+ country.code
1820
+ )) })
1821
+ ] })
1822
+ ] }),
1823
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1824
+ "input",
1825
+ {
1826
+ type: "tel",
1827
+ class: `pp-prechat-input pp-phone-number-input ${phoneError ? "error" : ""}`,
1828
+ placeholder: "612 345 678",
1829
+ value: phone,
1830
+ onInput: handlePhoneChange
1831
+ }
1832
+ )
1833
+ ] }),
1834
+ phoneError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-prechat-error", children: phoneError })
1835
+ ] });
1836
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-prechat", children: [
1837
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { class: "pp-prechat-title", children: "How can we reach you?" }),
1838
+ /* @__PURE__ */ (0, import_jsx_runtime.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." }),
1839
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: handleSubmit, children: [
1840
+ showChoice && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-prechat-tabs", children: [
1841
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1842
+ "button",
1843
+ {
1844
+ type: "button",
1845
+ class: `pp-prechat-tab ${activeTab === "email" ? "active" : ""}`,
1846
+ onClick: () => {
1847
+ setActiveTab("email");
1848
+ setPhoneError("");
1849
+ },
1850
+ children: [
1851
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmailIcon, {}),
1852
+ "Email"
1853
+ ]
1854
+ }
1855
+ ),
1856
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1857
+ "button",
1858
+ {
1859
+ type: "button",
1860
+ class: `pp-prechat-tab ${activeTab === "phone" ? "active" : ""}`,
1861
+ onClick: () => {
1862
+ setActiveTab("phone");
1863
+ setEmailError("");
1864
+ },
1865
+ children: [
1866
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PhoneIcon, {}),
1867
+ "Phone"
1868
+ ]
1869
+ }
1870
+ )
1871
+ ] }),
1872
+ showEmailOnly && renderEmailField(),
1873
+ showPhoneOnly && renderPhoneField(),
1874
+ showBoth && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1875
+ renderEmailField(),
1876
+ renderPhoneField()
1877
+ ] }),
1878
+ showChoice && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1879
+ activeTab === "email" && renderEmailField(),
1880
+ activeTab === "phone" && renderPhoneField()
1881
+ ] }),
1882
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "submit", class: "pp-prechat-submit", disabled: isSubmitting, children: isSubmitting ? "Submitting..." : "Start chatting" }),
1883
+ !config.required && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", class: "pp-prechat-skip", onClick: onSkip, children: "Skip for now" })
1884
+ ] })
1885
+ ] });
1112
1886
  }
1113
1887
 
1114
1888
  // src/components/ChatWidget.tsx
1115
- var import_jsx_runtime = require("preact/jsx-runtime");
1889
+ var import_jsx_runtime2 = require("preact/jsx-runtime");
1116
1890
  function formatDateSeparator(date) {
1117
1891
  const now = /* @__PURE__ */ new Date();
1118
1892
  const messageDate = new Date(date);
@@ -1132,28 +1906,31 @@ function getDateKey(date) {
1132
1906
  return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
1133
1907
  }
1134
1908
  function ChatWidget({ client: client2, config: initialConfig }) {
1135
- const [isOpen, setIsOpen] = (0, import_hooks.useState)(false);
1136
- const [messages, setMessages] = (0, import_hooks.useState)([]);
1137
- const [inputValue, setInputValue] = (0, import_hooks.useState)("");
1138
- const [isTyping, setIsTyping] = (0, import_hooks.useState)(false);
1139
- const [operatorOnline, setOperatorOnline] = (0, import_hooks.useState)(false);
1140
- const [isConnected, setIsConnected] = (0, import_hooks.useState)(false);
1141
- const [unreadCount, setUnreadCount] = (0, import_hooks.useState)(0);
1142
- const [pendingAttachments, setPendingAttachments] = (0, import_hooks.useState)([]);
1143
- const [isUploading, setIsUploading] = (0, import_hooks.useState)(false);
1144
- const [replyingTo, setReplyingTo] = (0, import_hooks.useState)(null);
1145
- const [editingMessage, setEditingMessage] = (0, import_hooks.useState)(null);
1146
- const [editContent, setEditContent] = (0, import_hooks.useState)("");
1147
- const [messageMenu, setMessageMenu] = (0, import_hooks.useState)(null);
1148
- const [isDragging, setIsDragging] = (0, import_hooks.useState)(false);
1149
- const [hoveredMessageId, setHoveredMessageId] = (0, import_hooks.useState)(null);
1150
- const [longPressTimer, setLongPressTimer] = (0, import_hooks.useState)(null);
1151
- const [config, setConfig] = (0, import_hooks.useState)(initialConfig);
1152
- const messagesEndRef = (0, import_hooks.useRef)(null);
1153
- const inputRef = (0, import_hooks.useRef)(null);
1154
- const fileInputRef = (0, import_hooks.useRef)(null);
1155
- const messagesContainerRef = (0, import_hooks.useRef)(null);
1156
- (0, import_hooks.useEffect)(() => {
1909
+ const [isOpen, setIsOpen] = (0, import_hooks2.useState)(false);
1910
+ const [messages, setMessages] = (0, import_hooks2.useState)([]);
1911
+ const [inputValue, setInputValue] = (0, import_hooks2.useState)("");
1912
+ const [isTyping, setIsTyping] = (0, import_hooks2.useState)(false);
1913
+ const [operatorOnline, setOperatorOnline] = (0, import_hooks2.useState)(false);
1914
+ const [isConnected, setIsConnected] = (0, import_hooks2.useState)(false);
1915
+ const [unreadCount, setUnreadCount] = (0, import_hooks2.useState)(0);
1916
+ const [pendingAttachments, setPendingAttachments] = (0, import_hooks2.useState)([]);
1917
+ const [isUploading, setIsUploading] = (0, import_hooks2.useState)(false);
1918
+ const [replyingTo, setReplyingTo] = (0, import_hooks2.useState)(null);
1919
+ const [editingMessage, setEditingMessage] = (0, import_hooks2.useState)(null);
1920
+ const [editContent, setEditContent] = (0, import_hooks2.useState)("");
1921
+ const [messageMenu, setMessageMenu] = (0, import_hooks2.useState)(null);
1922
+ const [isDragging, setIsDragging] = (0, import_hooks2.useState)(false);
1923
+ const [swipedMessageId, setSwipedMessageId] = (0, import_hooks2.useState)(null);
1924
+ const [swipeOffset, setSwipeOffset] = (0, import_hooks2.useState)(0);
1925
+ const touchStartRef = (0, import_hooks2.useRef)(null);
1926
+ const [config, setConfig] = (0, import_hooks2.useState)(initialConfig);
1927
+ const [preChatForm, setPreChatForm] = (0, import_hooks2.useState)(void 0);
1928
+ const [preChatSkipped, setPreChatSkipped] = (0, import_hooks2.useState)(false);
1929
+ const messagesEndRef = (0, import_hooks2.useRef)(null);
1930
+ const inputRef = (0, import_hooks2.useRef)(null);
1931
+ const fileInputRef = (0, import_hooks2.useRef)(null);
1932
+ const messagesContainerRef = (0, import_hooks2.useRef)(null);
1933
+ (0, import_hooks2.useEffect)(() => {
1157
1934
  const unsubOpen = client2.on("openChange", setIsOpen);
1158
1935
  const unsubMessage = client2.on("message", () => {
1159
1936
  setMessages([...client2.getMessages()]);
@@ -1169,6 +1946,10 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1169
1946
  setMessages(client2.getMessages());
1170
1947
  setOperatorOnline(client2.getSession()?.operatorOnline ?? false);
1171
1948
  setConfig(client2.getConfig());
1949
+ setPreChatForm(client2.getSession()?.preChatForm);
1950
+ });
1951
+ const unsubPreChat = client2.on("preChatCompleted", () => {
1952
+ setPreChatForm((prev) => prev ? { ...prev, completed: true } : prev);
1172
1953
  });
1173
1954
  const unsubConfig = client2.on("configUpdate", () => {
1174
1955
  setConfig(client2.getConfig());
@@ -1178,6 +1959,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1178
1959
  setMessages(client2.getMessages());
1179
1960
  setOperatorOnline(client2.getSession()?.operatorOnline ?? false);
1180
1961
  setConfig(client2.getConfig());
1962
+ setPreChatForm(client2.getSession()?.preChatForm);
1181
1963
  }
1182
1964
  return () => {
1183
1965
  unsubOpen();
@@ -1185,15 +1967,16 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1185
1967
  unsubTyping();
1186
1968
  unsubPresence();
1187
1969
  unsubConnect();
1970
+ unsubPreChat();
1188
1971
  unsubConfig();
1189
1972
  };
1190
1973
  }, [client2]);
1191
- (0, import_hooks.useEffect)(() => {
1974
+ (0, import_hooks2.useEffect)(() => {
1192
1975
  if (isOpen) {
1193
1976
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
1194
1977
  }
1195
1978
  }, [messages, isOpen]);
1196
- (0, import_hooks.useEffect)(() => {
1979
+ (0, import_hooks2.useEffect)(() => {
1197
1980
  if (isOpen) {
1198
1981
  setTimeout(() => {
1199
1982
  messagesEndRef.current?.scrollIntoView({ behavior: "auto" });
@@ -1202,7 +1985,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1202
1985
  setUnreadCount(0);
1203
1986
  }
1204
1987
  }, [isOpen]);
1205
- (0, import_hooks.useEffect)(() => {
1988
+ (0, import_hooks2.useEffect)(() => {
1206
1989
  if (!isOpen && messages.length > 0) {
1207
1990
  const unread = messages.filter(
1208
1991
  (msg) => msg.sender !== "visitor" && msg.status !== "read"
@@ -1210,7 +1993,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1210
1993
  setUnreadCount(unread);
1211
1994
  }
1212
1995
  }, [messages, isOpen]);
1213
- const markMessagesAsRead = (0, import_hooks.useCallback)(() => {
1996
+ const markMessagesAsRead = (0, import_hooks2.useCallback)(() => {
1214
1997
  if (!isOpen || !isConnected) return;
1215
1998
  const unreadMessages = messages.filter(
1216
1999
  (msg) => msg.sender !== "visitor" && msg.status !== "read"
@@ -1220,14 +2003,14 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1220
2003
  client2.sendReadStatus(messageIds, "read");
1221
2004
  }
1222
2005
  }, [isOpen, isConnected, messages, client2]);
1223
- (0, import_hooks.useEffect)(() => {
2006
+ (0, import_hooks2.useEffect)(() => {
1224
2007
  if (!isOpen || !isConnected) return;
1225
2008
  const timer = setTimeout(() => {
1226
2009
  markMessagesAsRead();
1227
2010
  }, 1e3);
1228
2011
  return () => clearTimeout(timer);
1229
2012
  }, [isOpen, isConnected, messages, markMessagesAsRead]);
1230
- (0, import_hooks.useEffect)(() => {
2013
+ (0, import_hooks2.useEffect)(() => {
1231
2014
  const handleVisibilityChange = () => {
1232
2015
  if (document.visibilityState === "visible" && isOpen) {
1233
2016
  markMessagesAsRead();
@@ -1236,7 +2019,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1236
2019
  document.addEventListener("visibilitychange", handleVisibilityChange);
1237
2020
  return () => document.removeEventListener("visibilitychange", handleVisibilityChange);
1238
2021
  }, [isOpen, markMessagesAsRead]);
1239
- (0, import_hooks.useEffect)(() => {
2022
+ (0, import_hooks2.useEffect)(() => {
1240
2023
  const unsubRead = client2.on(
1241
2024
  "read",
1242
2025
  () => {
@@ -1375,26 +2158,43 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1375
2158
  y: mouseEvent.clientY
1376
2159
  });
1377
2160
  };
1378
- const handleTouchStart = (message) => {
1379
- const timer = setTimeout(() => {
1380
- if (navigator.vibrate) navigator.vibrate(50);
1381
- setMessageMenu({
1382
- message,
1383
- x: window.innerWidth / 2 - 60,
1384
- // Center horizontally
1385
- y: window.innerHeight / 2 - 50
1386
- // Center vertically
1387
- });
1388
- }, 500);
1389
- setLongPressTimer(timer);
2161
+ const handleTouchStart = (e, message) => {
2162
+ const touch = e.touches[0];
2163
+ touchStartRef.current = { x: touch.clientX, y: touch.clientY, time: Date.now() };
2164
+ if (swipedMessageId && swipedMessageId !== message.id) {
2165
+ setSwipedMessageId(null);
2166
+ setSwipeOffset(0);
2167
+ }
1390
2168
  };
1391
- const handleTouchEnd = () => {
1392
- if (longPressTimer) {
1393
- clearTimeout(longPressTimer);
1394
- setLongPressTimer(null);
2169
+ const handleTouchMove = (e, message) => {
2170
+ if (!touchStartRef.current) return;
2171
+ const touch = e.touches[0];
2172
+ const deltaX = touch.clientX - touchStartRef.current.x;
2173
+ const deltaY = touch.clientY - touchStartRef.current.y;
2174
+ if (Math.abs(deltaY) > Math.abs(deltaX)) return;
2175
+ if (deltaX < 0) {
2176
+ const offset = Math.max(deltaX, -100);
2177
+ setSwipeOffset(offset);
2178
+ setSwipedMessageId(message.id);
1395
2179
  }
1396
2180
  };
1397
- (0, import_hooks.useEffect)(() => {
2181
+ const handleTouchEnd = (message) => {
2182
+ if (!touchStartRef.current) return;
2183
+ const elapsed = Date.now() - touchStartRef.current.time;
2184
+ if (swipeOffset < -50 || swipeOffset < -20 && elapsed < 200) {
2185
+ setSwipeOffset(-80);
2186
+ if (navigator.vibrate) navigator.vibrate(30);
2187
+ } else {
2188
+ setSwipeOffset(0);
2189
+ setSwipedMessageId(null);
2190
+ }
2191
+ touchStartRef.current = null;
2192
+ };
2193
+ const resetSwipe = () => {
2194
+ setSwipedMessageId(null);
2195
+ setSwipeOffset(0);
2196
+ };
2197
+ (0, import_hooks2.useEffect)(() => {
1398
2198
  if (!messageMenu) return;
1399
2199
  const handleClickOutside = () => setMessageMenu(null);
1400
2200
  document.addEventListener("click", handleClickOutside);
@@ -1410,7 +2210,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1410
2210
  }, 1500);
1411
2211
  }
1412
2212
  };
1413
- const dragCounterRef = (0, import_hooks.useRef)(0);
2213
+ const dragCounterRef = (0, import_hooks2.useRef)(0);
1414
2214
  const handleDragEnter = (e) => {
1415
2215
  e.preventDefault();
1416
2216
  e.stopPropagation();
@@ -1486,22 +2286,32 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1486
2286
  const theme = getTheme(config.theme ?? "auto");
1487
2287
  const primaryColor = config.primaryColor ?? "#6366f1";
1488
2288
  const actionIconColor = theme === "dark" ? "#9ca3af" : "#6b7280";
1489
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_preact.Fragment, { children: [
1490
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: styles(primaryColor, theme) }),
1491
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2289
+ const styleOptions = {
2290
+ primaryColor,
2291
+ theme,
2292
+ headerColor: config.headerColor,
2293
+ footerColor: config.footerColor,
2294
+ chatBackground: config.chatBackground,
2295
+ toggleColor: config.toggleColor
2296
+ };
2297
+ const shouldShowPreChat = preChatForm && preChatForm.enabled && !preChatForm.completed && !preChatSkipped && // Before first message: show immediately
2298
+ (preChatForm.timing === "before-first-message" && messages.length === 0 || preChatForm.timing === "after-first-message" && messages.some((m) => m.sender === "visitor"));
2299
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_preact.Fragment, { children: [
2300
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: styles(styleOptions) }),
2301
+ !isOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1492
2302
  "button",
1493
2303
  {
1494
2304
  class: `pp-toggle pp-${position}`,
1495
2305
  onClick: () => client2.toggleOpen(),
1496
- "aria-label": isOpen ? "Close chat" : "Open chat",
2306
+ "aria-label": "Open chat",
1497
2307
  children: [
1498
- isOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CloseIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChatIcon, {}),
1499
- !isOpen && unreadCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-unread-badge", children: unreadCount > 9 ? "9+" : unreadCount }),
1500
- !isOpen && unreadCount === 0 && operatorOnline && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-online-dot" })
2308
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatIcon, {}),
2309
+ unreadCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-unread-badge", children: unreadCount > 9 ? "9+" : unreadCount }),
2310
+ unreadCount === 0 && operatorOnline && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-online-dot" })
1501
2311
  ]
1502
2312
  }
1503
2313
  ),
1504
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2314
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1505
2315
  "div",
1506
2316
  {
1507
2317
  class: `pp-window pp-${position} pp-theme-${theme} ${isDragging ? "pp-dragging" : ""}`,
@@ -1510,36 +2320,49 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1510
2320
  onDragLeave: handleDragLeave,
1511
2321
  onDrop: handleDrop,
1512
2322
  children: [
1513
- isDragging && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-drop-overlay", children: [
1514
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-drop-icon", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AttachIcon, {}) }),
1515
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-drop-text", children: "Drop files to upload" })
2323
+ isDragging && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-drop-overlay", children: [
2324
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-drop-icon", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AttachIcon, {}) }),
2325
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-drop-text", children: "Drop files to upload" })
1516
2326
  ] }),
1517
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-header", children: [
1518
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-header-info", children: [
1519
- config.operatorAvatar && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: config.operatorAvatar, alt: "", class: "pp-avatar" }),
1520
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
1521
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-header-title", children: config.operatorName ?? "Support" }),
1522
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-header-status", children: operatorOnline ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1523
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-status-dot pp-online" }),
2327
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-header", children: [
2328
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-header-info", children: [
2329
+ config.operatorAvatar && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { src: config.operatorAvatar, alt: "", class: "pp-avatar" }),
2330
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
2331
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-header-title", children: config.operatorName ?? "Support" }),
2332
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-header-status", children: operatorOnline ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2333
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-status-dot pp-online" }),
1524
2334
  " Online"
1525
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1526
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-status-dot" }),
2335
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2336
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-status-dot" }),
1527
2337
  " Away"
1528
2338
  ] }) })
1529
2339
  ] })
1530
2340
  ] }),
1531
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2341
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1532
2342
  "button",
1533
2343
  {
1534
2344
  class: "pp-close-btn",
1535
2345
  onClick: () => client2.setOpen(false),
1536
2346
  "aria-label": "Close chat",
1537
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CloseIcon, {})
2347
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CloseIcon, {})
1538
2348
  }
1539
2349
  )
1540
2350
  ] }),
1541
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-messages", ref: messagesContainerRef, children: [
1542
- config.welcomeMessage && messages.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-welcome", children: config.welcomeMessage }),
2351
+ shouldShowPreChat && preChatForm && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2352
+ PreChatForm,
2353
+ {
2354
+ client: client2,
2355
+ config: preChatForm,
2356
+ onComplete: () => {
2357
+ setPreChatForm((prev) => prev ? { ...prev, completed: true } : prev);
2358
+ },
2359
+ onSkip: () => {
2360
+ setPreChatSkipped(true);
2361
+ }
2362
+ }
2363
+ ),
2364
+ !shouldShowPreChat && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-messages", ref: messagesContainerRef, onClick: () => swipedMessageId && resetSwipe(), children: [
2365
+ config.welcomeMessage && messages.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-welcome", children: config.welcomeMessage }),
1543
2366
  messages.map((msg, index) => {
1544
2367
  const isDeleted = !!msg.deletedAt;
1545
2368
  const isEdited = !!msg.editedAt;
@@ -1565,127 +2388,145 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1565
2388
  }
1566
2389
  }
1567
2390
  }
1568
- const isHovered = hoveredMessageId === msg.id;
1569
- const showActions = isHovered && !isDeleted;
1570
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_preact.Fragment, { children: [
1571
- showDateSeparator && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-date-separator", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: formatDateSeparator(msgDate) }) }),
1572
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1573
- "div",
1574
- {
1575
- id: `pp-msg-${msg.id}`,
1576
- class: `pp-message pp-message-${msg.sender} ${isDeleted ? "pp-message-deleted" : ""}`,
1577
- onContextMenu: (e) => handleMessageContextMenu(e, msg),
1578
- onMouseEnter: () => setHoveredMessageId(msg.id),
1579
- onMouseLeave: () => setHoveredMessageId(null),
1580
- onTouchStart: () => handleTouchStart(msg),
1581
- onTouchEnd: handleTouchEnd,
1582
- onTouchCancel: handleTouchEnd,
1583
- children: [
1584
- showActions && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: `pp-message-actions ${msg.sender === "visitor" ? "pp-actions-left" : "pp-actions-right"}`, children: [
1585
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1586
- "button",
2391
+ const isSwiped = swipedMessageId === msg.id;
2392
+ const msgSwipeOffset = isSwiped ? swipeOffset : 0;
2393
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_preact.Fragment, { children: [
2394
+ showDateSeparator && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-date-separator", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: formatDateSeparator(msgDate) }) }),
2395
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: `pp-message-swipe-container ${msg.sender === "visitor" ? "pp-swipe-left" : "pp-swipe-right"}`, children: [
2396
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-swipe-actions", children: [
2397
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2398
+ "button",
2399
+ {
2400
+ class: "pp-swipe-action pp-swipe-reply",
2401
+ onClick: () => {
2402
+ handleReply(msg);
2403
+ resetSwipe();
2404
+ },
2405
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReplyIcon, { color: "#fff" })
2406
+ }
2407
+ ),
2408
+ msg.sender === "visitor" && !isDeleted && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2409
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2410
+ "button",
2411
+ {
2412
+ class: "pp-swipe-action pp-swipe-edit",
2413
+ onClick: () => {
2414
+ handleStartEdit(msg);
2415
+ resetSwipe();
2416
+ },
2417
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EditIcon, { color: "#fff" })
2418
+ }
2419
+ ),
2420
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2421
+ "button",
2422
+ {
2423
+ class: "pp-swipe-action pp-swipe-delete",
2424
+ onClick: () => {
2425
+ handleDelete(msg);
2426
+ resetSwipe();
2427
+ },
2428
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DeleteIcon, { color: "#fff" })
2429
+ }
2430
+ )
2431
+ ] })
2432
+ ] }),
2433
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2434
+ "div",
2435
+ {
2436
+ id: `pp-msg-${msg.id}`,
2437
+ class: `pp-message pp-message-${msg.sender} ${isDeleted ? "pp-message-deleted" : ""}`,
2438
+ style: { transform: `translateX(${msgSwipeOffset}px)`, transition: touchStartRef.current ? "none" : "transform 0.2s ease-out" },
2439
+ onContextMenu: (e) => handleMessageContextMenu(e, msg),
2440
+ onTouchStart: (e) => handleTouchStart(e, msg),
2441
+ onTouchMove: (e) => handleTouchMove(e, msg),
2442
+ onTouchEnd: () => handleTouchEnd(msg),
2443
+ onTouchCancel: () => handleTouchEnd(msg),
2444
+ children: [
2445
+ replyData && (replyData.content || replyData.hasAttachment) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2446
+ "div",
1587
2447
  {
1588
- class: "pp-action-btn",
1589
- onClick: () => handleReply(msg),
1590
- title: "Reply",
1591
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReplyIcon, { color: actionIconColor })
2448
+ class: "pp-reply-quote pp-reply-quote-clickable",
2449
+ onClick: () => scrollToMessage(replyData.id),
2450
+ role: "button",
2451
+ tabIndex: 0,
2452
+ onKeyDown: (e) => e.key === "Enter" && scrollToMessage(replyData.id),
2453
+ children: [
2454
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-reply-sender", children: replyData.sender === "visitor" ? "You" : "Support" }),
2455
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-reply-content", children: replyData.deleted ? "Message deleted" : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2456
+ replyData.hasAttachment && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-reply-attachment-icon", children: replyData.attachmentType?.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
2457
+ replyData.content ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2458
+ (replyData.content || "").slice(0, 50),
2459
+ (replyData.content || "").length > 50 ? "..." : ""
2460
+ ] }) : replyData.attachmentType?.startsWith("image/") ? "Photo" : "File"
2461
+ ] }) })
2462
+ ]
1592
2463
  }
1593
2464
  ),
1594
- msg.sender === "visitor" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1595
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1596
- "button",
1597
- {
1598
- class: "pp-action-btn",
1599
- onClick: () => handleStartEdit(msg),
1600
- title: "Edit",
1601
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditIcon, { color: actionIconColor })
1602
- }
1603
- ),
1604
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1605
- "button",
1606
- {
1607
- class: "pp-action-btn pp-action-delete",
1608
- onClick: () => handleDelete(msg),
1609
- title: "Delete",
1610
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DeleteIcon, { color: actionIconColor })
1611
- }
1612
- )
2465
+ isDeleted ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-message-content pp-deleted-content", children: [
2466
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-deleted-icon", children: "\u{1F5D1}\uFE0F" }),
2467
+ " Message deleted"
2468
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2469
+ msg.content && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-message-content", children: [
2470
+ msg.content,
2471
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { class: "pp-message-time", children: [
2472
+ formatTime(msg.timestamp),
2473
+ isEdited && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-edited-badge", children: "edited" }),
2474
+ msg.sender === "ai" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-ai-badge", children: "AI" }),
2475
+ msg.sender === "visitor" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: `pp-status pp-status-${msg.status ?? "sent"}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StatusIcon, { status: msg.status }) })
2476
+ ] })
2477
+ ] }),
2478
+ msg.attachments && msg.attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-message-attachments", children: [
2479
+ msg.attachments.map((att) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AttachmentDisplay, { attachment: att }, att.id)),
2480
+ !msg.content && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { class: "pp-message-time pp-attachment-time", children: [
2481
+ formatTime(msg.timestamp),
2482
+ isEdited && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-edited-badge", children: "edited" }),
2483
+ msg.sender === "ai" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-ai-badge", children: "AI" }),
2484
+ msg.sender === "visitor" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: `pp-status pp-status-${msg.status ?? "sent"}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StatusIcon, { status: msg.status }) })
2485
+ ] })
2486
+ ] })
1613
2487
  ] })
1614
- ] }),
1615
- replyData && (replyData.content || replyData.hasAttachment) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1616
- "div",
1617
- {
1618
- class: "pp-reply-quote pp-reply-quote-clickable",
1619
- onClick: () => scrollToMessage(replyData.id),
1620
- role: "button",
1621
- tabIndex: 0,
1622
- onKeyDown: (e) => e.key === "Enter" && scrollToMessage(replyData.id),
1623
- children: [
1624
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-reply-sender", children: replyData.sender === "visitor" ? "You" : "Support" }),
1625
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-reply-content", children: replyData.deleted ? "Message deleted" : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1626
- replyData.hasAttachment && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-reply-attachment-icon", children: replyData.attachmentType?.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
1627
- replyData.content ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1628
- (replyData.content || "").slice(0, 50),
1629
- (replyData.content || "").length > 50 ? "..." : ""
1630
- ] }) : replyData.attachmentType?.startsWith("image/") ? "Photo" : "File"
1631
- ] }) })
1632
- ]
1633
- }
1634
- ),
1635
- isDeleted ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-message-content pp-deleted-content", children: [
1636
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-deleted-icon", children: "\u{1F5D1}\uFE0F" }),
1637
- " Message deleted"
1638
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1639
- msg.content && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-message-content", children: msg.content }),
1640
- msg.attachments && msg.attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-message-attachments", children: msg.attachments.map((att) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AttachmentDisplay, { attachment: att }, att.id)) })
1641
- ] }),
1642
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-message-time", children: [
1643
- formatTime(msg.timestamp),
1644
- isEdited && !isDeleted && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-edited-badge", children: "edited" }),
1645
- msg.sender === "ai" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-ai-badge", children: "AI" }),
1646
- msg.sender === "visitor" && !isDeleted && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: `pp-status pp-status-${msg.status ?? "sent"}`, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatusIcon, { status: msg.status }) })
1647
- ] })
1648
- ]
1649
- }
1650
- )
2488
+ ]
2489
+ }
2490
+ )
2491
+ ] })
1651
2492
  ] }, msg.id);
1652
2493
  }),
1653
- isTyping && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-message pp-message-operator pp-typing", children: [
1654
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {}),
1655
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {}),
1656
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {})
2494
+ isTyping && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-message pp-message-operator pp-typing", children: [
2495
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {}),
2496
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {}),
2497
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {})
1657
2498
  ] }),
1658
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: messagesEndRef })
2499
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref: messagesEndRef })
1659
2500
  ] }),
1660
- messageMenu && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2501
+ messageMenu && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1661
2502
  "div",
1662
2503
  {
1663
2504
  class: "pp-message-menu",
1664
2505
  style: { top: `${messageMenu.y}px`, left: `${messageMenu.x}px` },
1665
2506
  children: [
1666
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { onClick: () => handleReply(messageMenu.message), children: [
1667
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReplyIcon, { color: actionIconColor }),
2507
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { onClick: () => handleReply(messageMenu.message), children: [
2508
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReplyIcon, { color: actionIconColor }),
1668
2509
  " Reply"
1669
2510
  ] }),
1670
- messageMenu.message.sender === "visitor" && !messageMenu.message.deletedAt && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1671
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { onClick: () => handleStartEdit(messageMenu.message), children: [
1672
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditIcon, { color: actionIconColor }),
2511
+ messageMenu.message.sender === "visitor" && !messageMenu.message.deletedAt && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2512
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { onClick: () => handleStartEdit(messageMenu.message), children: [
2513
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EditIcon, { color: actionIconColor }),
1673
2514
  " Edit"
1674
2515
  ] }),
1675
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { class: "pp-menu-delete", onClick: () => handleDelete(messageMenu.message), children: [
1676
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DeleteIcon, { color: "#ef4444" }),
2516
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { class: "pp-menu-delete", onClick: () => handleDelete(messageMenu.message), children: [
2517
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DeleteIcon, { color: "#ef4444" }),
1677
2518
  " Delete"
1678
2519
  ] })
1679
2520
  ] })
1680
2521
  ]
1681
2522
  }
1682
2523
  ),
1683
- editingMessage && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-edit-modal", children: [
1684
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-edit-header", children: [
1685
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Edit message" }),
1686
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: handleCancelEdit, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CloseIcon, {}) })
2524
+ editingMessage && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-edit-modal", children: [
2525
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-edit-header", children: [
2526
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Edit message" }),
2527
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: handleCancelEdit, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CloseIcon, {}) })
1687
2528
  ] }),
1688
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2529
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1689
2530
  "textarea",
1690
2531
  {
1691
2532
  class: "pp-edit-input",
@@ -1694,41 +2535,41 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1694
2535
  autoFocus: true
1695
2536
  }
1696
2537
  ),
1697
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-edit-actions", children: [
1698
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { class: "pp-edit-cancel", onClick: handleCancelEdit, children: "Cancel" }),
1699
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { class: "pp-edit-save", onClick: handleSaveEdit, disabled: !editContent.trim(), children: "Save" })
2538
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-edit-actions", children: [
2539
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { class: "pp-edit-cancel", onClick: handleCancelEdit, children: "Cancel" }),
2540
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { class: "pp-edit-save", onClick: handleSaveEdit, disabled: !editContent.trim(), children: "Save" })
1700
2541
  ] })
1701
2542
  ] }),
1702
- replyingTo && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-reply-preview", children: [
1703
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-reply-preview-content", children: [
1704
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-reply-label", children: "Replying to" }),
1705
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { class: "pp-reply-text", children: [
1706
- replyingTo.attachments && replyingTo.attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-reply-attachment-icon", children: replyingTo.attachments[0].mimeType.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
1707
- replyingTo.content ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
2543
+ replyingTo && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-reply-preview", children: [
2544
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-reply-preview-content", children: [
2545
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-reply-label", children: "Replying to" }),
2546
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { class: "pp-reply-text", children: [
2547
+ replyingTo.attachments && replyingTo.attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-reply-attachment-icon", children: replyingTo.attachments[0].mimeType.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
2548
+ replyingTo.content ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
1708
2549
  replyingTo.content.slice(0, 50),
1709
2550
  replyingTo.content.length > 50 ? "..." : ""
1710
2551
  ] }) : replyingTo.attachments?.[0]?.mimeType.startsWith("image/") ? "Photo" : "File"
1711
2552
  ] })
1712
2553
  ] }),
1713
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { class: "pp-reply-cancel", onClick: handleCancelReply, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CloseIcon, {}) })
2554
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { class: "pp-reply-cancel", onClick: handleCancelReply, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CloseIcon, {}) })
1714
2555
  ] }),
1715
- pendingAttachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-attachments-preview", children: pendingAttachments.map((pending) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: `pp-attachment-preview pp-attachment-${pending.status}`, children: [
1716
- pending.preview ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: pending.preview, alt: pending.file.name, class: "pp-preview-img" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-preview-file", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileIcon, { mimeType: pending.file.type }) }),
1717
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2556
+ pendingAttachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-attachments-preview", children: pendingAttachments.map((pending) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: `pp-attachment-preview pp-attachment-${pending.status}`, children: [
2557
+ pending.preview ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { src: pending.preview, alt: pending.file.name, class: "pp-preview-img" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-preview-file", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FileIcon, { mimeType: pending.file.type }) }),
2558
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1718
2559
  "button",
1719
2560
  {
1720
2561
  class: "pp-remove-attachment",
1721
2562
  onClick: () => handleRemoveAttachment(pending.id),
1722
2563
  "aria-label": "Remove attachment",
1723
2564
  type: "button",
1724
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CloseIcon, {})
2565
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CloseIcon, {})
1725
2566
  }
1726
2567
  ),
1727
- pending.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-upload-progress", style: { width: `${pending.progress}%` } }),
1728
- pending.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-upload-error", title: pending.error, children: "!" })
2568
+ pending.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-upload-progress", style: { width: `${pending.progress}%` } }),
2569
+ pending.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-upload-error", title: pending.error, children: "!" })
1729
2570
  ] }, pending.id)) }),
1730
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { class: "pp-input-form", onSubmit: handleSubmit, children: [
1731
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2571
+ !shouldShowPreChat && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { class: "pp-input-form", onSubmit: handleSubmit, children: [
2572
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1732
2573
  "input",
1733
2574
  {
1734
2575
  ref: (el) => {
@@ -1743,7 +2584,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1743
2584
  multiple: true
1744
2585
  }
1745
2586
  ),
1746
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2587
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1747
2588
  "button",
1748
2589
  {
1749
2590
  type: "button",
@@ -1751,10 +2592,10 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1751
2592
  onClick: () => fileInputRef.current?.click(),
1752
2593
  disabled: !isConnected || isUploading,
1753
2594
  "aria-label": "Attach file",
1754
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AttachIcon, {})
2595
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AttachIcon, {})
1755
2596
  }
1756
2597
  ),
1757
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2598
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1758
2599
  "input",
1759
2600
  {
1760
2601
  ref: inputRef,
@@ -1766,20 +2607,20 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1766
2607
  disabled: !isConnected
1767
2608
  }
1768
2609
  ),
1769
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2610
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1770
2611
  "button",
1771
2612
  {
1772
2613
  type: "submit",
1773
2614
  class: "pp-send-btn",
1774
2615
  disabled: !inputValue.trim() && pendingAttachments.filter((a) => a.status === "ready").length === 0 || !isConnected || isUploading,
1775
2616
  "aria-label": "Send message",
1776
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SendIcon, {})
2617
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SendIcon, {})
1777
2618
  }
1778
2619
  )
1779
2620
  ] }),
1780
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-footer", children: [
2621
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-footer", children: [
1781
2622
  "Powered by ",
1782
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: "https://pocketping.io", target: "_blank", rel: "noopener", children: "PocketPing" })
2623
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { href: "https://pocketping.io", target: "_blank", rel: "noopener", children: "PocketPing" })
1783
2624
  ] })
1784
2625
  ]
1785
2626
  }
@@ -1807,90 +2648,90 @@ function formatTime(timestamp) {
1807
2648
  return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
1808
2649
  }
1809
2650
  function ChatIcon() {
1810
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: /* @__PURE__ */ (0, import_jsx_runtime.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" }) });
2651
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: /* @__PURE__ */ (0, import_jsx_runtime2.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" }) });
1811
2652
  }
1812
2653
  function CloseIcon() {
1813
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1814
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1815
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2654
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2655
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2656
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1816
2657
  ] });
1817
2658
  }
1818
2659
  function SendIcon() {
1819
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1820
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
1821
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
2660
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2661
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
2662
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
1822
2663
  ] });
1823
2664
  }
1824
2665
  function StatusIcon({ status }) {
1825
2666
  if (!status || status === "sending" || status === "sent") {
1826
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "3 8 7 12 13 4" }) });
2667
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "3 8 7 12 13 4" }) });
1827
2668
  }
1828
2669
  if (status === "delivered") {
1829
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 20 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check-double", children: [
1830
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "1 8 5 12 11 4" }),
1831
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "7 8 11 12 17 4" })
2670
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 20 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check-double", children: [
2671
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "1 8 5 12 11 4" }),
2672
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "7 8 11 12 17 4" })
1832
2673
  ] });
1833
2674
  }
1834
2675
  if (status === "read") {
1835
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 20 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check-double pp-check-read", children: [
1836
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "1 8 5 12 11 4" }),
1837
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "7 8 11 12 17 4" })
2676
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 20 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check-double pp-check-read", children: [
2677
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "1 8 5 12 11 4" }),
2678
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "7 8 11 12 17 4" })
1838
2679
  ] });
1839
2680
  }
1840
2681
  return null;
1841
2682
  }
1842
2683
  function AttachIcon() {
1843
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: /* @__PURE__ */ (0, import_jsx_runtime.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" }) });
2684
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: /* @__PURE__ */ (0, import_jsx_runtime2.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" }) });
1844
2685
  }
1845
2686
  function ReplyIcon({ color, size = 16 }) {
1846
2687
  const strokeColor = color || "currentColor";
1847
- return /* @__PURE__ */ (0, import_jsx_runtime.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: [
1848
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "9 17 4 12 9 7" }),
1849
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M20 18v-2a4 4 0 0 0-4-4H4" })
2688
+ return /* @__PURE__ */ (0, import_jsx_runtime2.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: [
2689
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "9 17 4 12 9 7" }),
2690
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M20 18v-2a4 4 0 0 0-4-4H4" })
1850
2691
  ] });
1851
2692
  }
1852
2693
  function EditIcon({ color, size = 16 }) {
1853
2694
  const strokeColor = color || "currentColor";
1854
- return /* @__PURE__ */ (0, import_jsx_runtime.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__ */ (0, import_jsx_runtime.jsx)("path", { d: "M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z" }) });
2695
+ return /* @__PURE__ */ (0, import_jsx_runtime2.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__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z" }) });
1855
2696
  }
1856
2697
  function DeleteIcon({ color, size = 16 }) {
1857
2698
  const strokeColor = color || "currentColor";
1858
- return /* @__PURE__ */ (0, import_jsx_runtime.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: [
1859
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "3 6 5 6 21 6" }),
1860
- /* @__PURE__ */ (0, import_jsx_runtime.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" })
2699
+ return /* @__PURE__ */ (0, import_jsx_runtime2.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: [
2700
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "3 6 5 6 21 6" }),
2701
+ /* @__PURE__ */ (0, import_jsx_runtime2.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" })
1861
2702
  ] });
1862
2703
  }
1863
2704
  function FileIcon({ mimeType }) {
1864
2705
  if (mimeType === "application/pdf") {
1865
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1866
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1867
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "14 2 14 8 20 8" }),
1868
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 15h6" }),
1869
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 11h6" })
2706
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2707
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
2708
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "14 2 14 8 20 8" }),
2709
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 15h6" }),
2710
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 11h6" })
1870
2711
  ] });
1871
2712
  }
1872
2713
  if (mimeType.startsWith("audio/")) {
1873
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1874
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 18V5l12-2v13" }),
1875
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "6", cy: "18", r: "3" }),
1876
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "18", cy: "16", r: "3" })
2714
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2715
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 18V5l12-2v13" }),
2716
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "6", cy: "18", r: "3" }),
2717
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "18", cy: "16", r: "3" })
1877
2718
  ] });
1878
2719
  }
1879
2720
  if (mimeType.startsWith("video/")) {
1880
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1881
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2.18", ry: "2.18" }),
1882
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "7", y1: "2", x2: "7", y2: "22" }),
1883
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "17", y1: "2", x2: "17", y2: "22" }),
1884
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
1885
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "2", y1: "7", x2: "7", y2: "7" }),
1886
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "2", y1: "17", x2: "7", y2: "17" }),
1887
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "17", y1: "17", x2: "22", y2: "17" }),
1888
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "17", y1: "7", x2: "22", y2: "7" })
2721
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2722
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2.18", ry: "2.18" }),
2723
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "7", y1: "2", x2: "7", y2: "22" }),
2724
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "17", y1: "2", x2: "17", y2: "22" }),
2725
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
2726
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "2", y1: "7", x2: "7", y2: "7" }),
2727
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "2", y1: "17", x2: "7", y2: "17" }),
2728
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "17", y1: "17", x2: "22", y2: "17" }),
2729
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "17", y1: "7", x2: "22", y2: "7" })
1889
2730
  ] });
1890
2731
  }
1891
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1892
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1893
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "14 2 14 8 20 8" })
2732
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2733
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
2734
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "14 2 14 8 20 8" })
1894
2735
  ] });
1895
2736
  }
1896
2737
  function AttachmentDisplay({ attachment }) {
@@ -1903,22 +2744,22 @@ function AttachmentDisplay({ attachment }) {
1903
2744
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
1904
2745
  };
1905
2746
  if (isImage) {
1906
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-image", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: attachment.thumbnailUrl || attachment.url, alt: attachment.filename }) });
2747
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-image", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { src: attachment.thumbnailUrl || attachment.url, alt: attachment.filename }) });
1907
2748
  }
1908
2749
  if (isAudio) {
1909
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-attachment pp-attachment-audio", children: [
1910
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("audio", { controls: true, preload: "metadata", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("source", { src: attachment.url, type: attachment.mimeType }) }),
1911
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-attachment-name", children: attachment.filename })
2750
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-attachment pp-attachment-audio", children: [
2751
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("audio", { controls: true, preload: "metadata", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("source", { src: attachment.url, type: attachment.mimeType }) }),
2752
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-attachment-name", children: attachment.filename })
1912
2753
  ] });
1913
2754
  }
1914
2755
  if (isVideo) {
1915
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-attachment pp-attachment-video", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("video", { controls: true, preload: "metadata", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("source", { src: attachment.url, type: attachment.mimeType }) }) });
2756
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-attachment pp-attachment-video", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("video", { controls: true, preload: "metadata", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("source", { src: attachment.url, type: attachment.mimeType }) }) });
1916
2757
  }
1917
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-file", children: [
1918
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileIcon, { mimeType: attachment.mimeType }),
1919
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-attachment-info", children: [
1920
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-attachment-name", children: attachment.filename }),
1921
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-attachment-size", children: formatSize(attachment.size) })
2758
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-file", children: [
2759
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FileIcon, { mimeType: attachment.mimeType }),
2760
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-attachment-info", children: [
2761
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-attachment-name", children: attachment.filename }),
2762
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-attachment-size", children: formatSize(attachment.size) })
1922
2763
  ] })
1923
2764
  ] });
1924
2765
  }
@@ -1984,7 +2825,8 @@ var PocketPingClient = class {
1984
2825
  visitorId: response.visitorId,
1985
2826
  operatorOnline: response.operatorOnline ?? false,
1986
2827
  messages: response.messages ?? [],
1987
- identity: response.identity || storedIdentity || void 0
2828
+ identity: response.identity || storedIdentity || void 0,
2829
+ preChatForm: response.preChatForm
1988
2830
  };
1989
2831
  if (response.operatorName) {
1990
2832
  this.config.operatorName = response.operatorName;
@@ -1995,6 +2837,18 @@ var PocketPingClient = class {
1995
2837
  if (response.primaryColor) {
1996
2838
  this.config.primaryColor = response.primaryColor;
1997
2839
  }
2840
+ if (response.headerColor) {
2841
+ this.config.headerColor = response.headerColor;
2842
+ }
2843
+ if (response.footerColor) {
2844
+ this.config.footerColor = response.footerColor;
2845
+ }
2846
+ if (response.chatBackground) {
2847
+ this.config.chatBackground = response.chatBackground;
2848
+ }
2849
+ if (response.toggleColor) {
2850
+ this.config.toggleColor = response.toggleColor;
2851
+ }
1998
2852
  if (response.welcomeMessage) {
1999
2853
  this.config.welcomeMessage = response.welcomeMessage;
2000
2854
  }
@@ -2002,6 +2856,10 @@ var PocketPingClient = class {
2002
2856
  operatorName: this.config.operatorName,
2003
2857
  operatorAvatar: this.config.operatorAvatar,
2004
2858
  primaryColor: this.config.primaryColor,
2859
+ headerColor: this.config.headerColor,
2860
+ footerColor: this.config.footerColor,
2861
+ chatBackground: this.config.chatBackground,
2862
+ toggleColor: this.config.toggleColor,
2005
2863
  welcomeMessage: this.config.welcomeMessage
2006
2864
  });
2007
2865
  this.storeSessionId(response.sessionId);
@@ -2340,6 +3198,36 @@ var PocketPingClient = class {
2340
3198
  }
2341
3199
  }
2342
3200
  }
3201
+ /**
3202
+ * Submit pre-chat form data (email and/or phone)
3203
+ * @param data - Form data containing email and/or phone
3204
+ */
3205
+ async submitPreChat(data) {
3206
+ if (!this.session) {
3207
+ throw new Error("[PocketPing] Not connected");
3208
+ }
3209
+ if (!data.email && !data.phone) {
3210
+ throw new Error("[PocketPing] Either email or phone is required");
3211
+ }
3212
+ try {
3213
+ await this.fetch("/prechat", {
3214
+ method: "POST",
3215
+ body: JSON.stringify({
3216
+ sessionId: this.session.sessionId,
3217
+ email: data.email,
3218
+ phone: data.phone,
3219
+ phoneCountry: data.phoneCountry
3220
+ })
3221
+ });
3222
+ if (this.session.preChatForm) {
3223
+ this.session.preChatForm.completed = true;
3224
+ }
3225
+ this.emit("preChatCompleted", data);
3226
+ } catch (err) {
3227
+ console.error("[PocketPing] Failed to submit pre-chat form:", err);
3228
+ throw err;
3229
+ }
3230
+ }
2343
3231
  /**
2344
3232
  * Reset the user identity and optionally start a new session
2345
3233
  * Call on user logout to clear user data
@@ -2989,6 +3877,12 @@ var PocketPingClient = class {
2989
3877
  this.session.messages.push(message);
2990
3878
  this.emit("message", message);
2991
3879
  this.config.onMessage?.(message);
3880
+ if (message.sender !== "visitor" && !this.isOpen) {
3881
+ const autoOpen = this.config.autoOpenOnMessage ?? true;
3882
+ if (autoOpen) {
3883
+ this.setOpen(true);
3884
+ }
3885
+ }
2992
3886
  }
2993
3887
  }
2994
3888
  if (message.sender !== "visitor") {
@@ -3147,6 +4041,12 @@ var PocketPingClient = class {
3147
4041
  this.session.messages.push(message);
3148
4042
  this.emit("message", message);
3149
4043
  this.config.onMessage?.(message);
4044
+ if (message.sender !== "visitor" && !this.isOpen) {
4045
+ const autoOpen = this.config.autoOpenOnMessage ?? true;
4046
+ if (autoOpen) {
4047
+ this.setOpen(true);
4048
+ }
4049
+ }
3150
4050
  }
3151
4051
  }
3152
4052
  } catch (err) {