@pocketping/widget 1.5.2 → 1.7.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,7 +44,7 @@ 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
50
  function styles(primaryColor, theme) {
@@ -65,6 +65,17 @@ function styles(primaryColor, theme) {
65
65
  color: ${colors.text};
66
66
  }
67
67
 
68
+ #pocketping-container,
69
+ #pocketping-container * {
70
+ box-sizing: border-box;
71
+ }
72
+
73
+ #pocketping-container img,
74
+ #pocketping-container video {
75
+ max-width: 100%;
76
+ height: auto;
77
+ }
78
+
68
79
  .pp-toggle {
69
80
  position: fixed;
70
81
  width: 56px;
@@ -189,7 +200,7 @@ function styles(primaryColor, theme) {
189
200
  display: flex;
190
201
  align-items: center;
191
202
  justify-content: space-between;
192
- padding: 16px;
203
+ padding: 12px 14px;
193
204
  background: ${primaryColor};
194
205
  color: white;
195
206
  }
@@ -197,24 +208,24 @@ function styles(primaryColor, theme) {
197
208
  .pp-header-info {
198
209
  display: flex;
199
210
  align-items: center;
200
- gap: 12px;
211
+ gap: 10px;
201
212
  }
202
213
 
203
214
  .pp-avatar {
204
- width: 40px;
205
- height: 40px;
215
+ width: 36px;
216
+ height: 36px;
206
217
  border-radius: 50%;
207
218
  object-fit: cover;
208
219
  }
209
220
 
210
221
  .pp-header-title {
211
222
  font-weight: 600;
212
- font-size: 16px;
223
+ font-size: 15px;
213
224
  }
214
225
 
215
226
  .pp-header-status {
216
- font-size: 12px;
217
- opacity: 0.9;
227
+ font-size: 11px;
228
+ opacity: 0.85;
218
229
  display: flex;
219
230
  align-items: center;
220
231
  gap: 4px;
@@ -260,10 +271,14 @@ function styles(primaryColor, theme) {
260
271
  .pp-messages {
261
272
  flex: 1;
262
273
  overflow-y: auto;
263
- padding: 16px;
274
+ padding: 32px 12px 12px 12px;
264
275
  display: flex;
265
276
  flex-direction: column;
266
- gap: 12px;
277
+ gap: 3px;
278
+ overscroll-behavior: contain;
279
+ -webkit-overflow-scrolling: touch;
280
+ /* Ensure proper stacking context for positioned elements */
281
+ position: relative;
267
282
  }
268
283
 
269
284
  .pp-welcome {
@@ -273,20 +288,110 @@ function styles(primaryColor, theme) {
273
288
  font-size: 13px;
274
289
  }
275
290
 
291
+ .pp-date-separator {
292
+ display: flex;
293
+ align-items: center;
294
+ justify-content: center;
295
+ margin: 16px 0 12px;
296
+ }
297
+
298
+ .pp-date-separator span {
299
+ background: ${colors.bgSecondary};
300
+ color: ${colors.textSecondary};
301
+ font-size: 11px;
302
+ padding: 4px 12px;
303
+ border-radius: 12px;
304
+ font-weight: 500;
305
+ }
306
+
307
+ /* Swipe container for mobile actions */
308
+ .pp-message-swipe-container {
309
+ position: relative;
310
+ display: flex;
311
+ align-items: stretch;
312
+ overflow: visible;
313
+ touch-action: pan-y;
314
+ }
315
+
316
+ .pp-swipe-left {
317
+ justify-content: flex-end;
318
+ }
319
+
320
+ .pp-swipe-right {
321
+ justify-content: flex-start;
322
+ }
323
+
324
+ .pp-swipe-actions {
325
+ position: absolute;
326
+ right: 0;
327
+ top: 0;
328
+ bottom: 0;
329
+ display: flex;
330
+ align-items: center;
331
+ gap: 4px;
332
+ padding-right: 8px;
333
+ }
334
+
335
+ .pp-swipe-left .pp-swipe-actions {
336
+ right: 0;
337
+ left: auto;
338
+ }
339
+
340
+ .pp-swipe-right .pp-swipe-actions {
341
+ left: 0;
342
+ right: auto;
343
+ padding-left: 8px;
344
+ padding-right: 0;
345
+ }
346
+
347
+ .pp-swipe-action {
348
+ width: 32px;
349
+ height: 32px;
350
+ border: none;
351
+ border-radius: 50%;
352
+ cursor: pointer;
353
+ display: flex;
354
+ align-items: center;
355
+ justify-content: center;
356
+ opacity: 0.9;
357
+ }
358
+
359
+ .pp-swipe-action svg {
360
+ width: 16px;
361
+ height: 16px;
362
+ }
363
+
364
+ .pp-swipe-reply {
365
+ background: ${primaryColor};
366
+ }
367
+
368
+ .pp-swipe-edit {
369
+ background: #3b82f6;
370
+ }
371
+
372
+ .pp-swipe-delete {
373
+ background: #ef4444;
374
+ }
375
+
276
376
  .pp-message {
277
- max-width: 80%;
278
- padding: 10px 14px;
279
- border-radius: 16px;
377
+ max-width: 85%;
378
+ padding: 6px 10px;
379
+ border-radius: 12px;
280
380
  word-wrap: break-word;
281
381
  position: relative;
282
382
  user-select: text;
283
383
  -webkit-user-select: text;
384
+ font-size: 14px;
385
+ line-height: 1.35;
386
+ display: flex;
387
+ flex-direction: column;
388
+ will-change: transform;
284
389
  }
285
390
 
286
391
  /* Hover actions container - positioned above message (Slack style) */
287
392
  .pp-message-actions {
288
393
  position: absolute;
289
- top: -28px;
394
+ top: -32px;
290
395
  display: flex;
291
396
  gap: 2px;
292
397
  background: ${colors.bg};
@@ -299,6 +404,8 @@ function styles(primaryColor, theme) {
299
404
  z-index: 10;
300
405
  /* Reset color inheritance from message */
301
406
  color: ${colors.textSecondary};
407
+ /* Ensure actions don't interfere with layout */
408
+ pointer-events: auto;
302
409
  }
303
410
 
304
411
  @keyframes pp-actions-fade-in {
@@ -372,7 +479,8 @@ function styles(primaryColor, theme) {
372
479
  align-self: flex-end;
373
480
  background: ${primaryColor};
374
481
  color: white;
375
- border-bottom-right-radius: 4px;
482
+ border-bottom-right-radius: 3px;
483
+ margin-left: 32px;
376
484
  }
377
485
 
378
486
  .pp-message-operator,
@@ -380,19 +488,32 @@ function styles(primaryColor, theme) {
380
488
  align-self: flex-start;
381
489
  background: ${colors.messageBg};
382
490
  color: ${colors.text};
383
- border-bottom-left-radius: 4px;
491
+ border-bottom-left-radius: 3px;
492
+ margin-right: 32px;
493
+ }
494
+
495
+ /* Add spacing between different senders */
496
+ .pp-message-visitor + .pp-message-operator,
497
+ .pp-message-visitor + .pp-message-ai,
498
+ .pp-message-operator + .pp-message-visitor,
499
+ .pp-message-ai + .pp-message-visitor {
500
+ margin-top: 8px;
384
501
  }
385
502
 
386
503
  .pp-message-content {
387
- margin-bottom: 4px;
504
+ display: block;
505
+ flex: 1;
388
506
  }
389
507
 
390
508
  .pp-message-time {
391
- font-size: 11px;
392
- opacity: 0.7;
509
+ font-size: 10px;
510
+ opacity: 0.6;
393
511
  display: flex;
394
512
  align-items: center;
395
- gap: 4px;
513
+ gap: 3px;
514
+ justify-content: flex-end;
515
+ margin-top: 8px;
516
+ flex-shrink: 0;
396
517
  }
397
518
 
398
519
  .pp-ai-badge {
@@ -429,13 +550,13 @@ function styles(primaryColor, theme) {
429
550
 
430
551
  .pp-typing {
431
552
  display: flex;
432
- gap: 4px;
433
- padding: 14px 18px;
553
+ gap: 3px;
554
+ padding: 8px 12px;
434
555
  }
435
556
 
436
557
  .pp-typing span {
437
- width: 8px;
438
- height: 8px;
558
+ width: 6px;
559
+ height: 6px;
439
560
  background: ${colors.textSecondary};
440
561
  border-radius: 50%;
441
562
  animation: pp-bounce 1.4s infinite ease-in-out both;
@@ -451,14 +572,18 @@ function styles(primaryColor, theme) {
451
572
 
452
573
  .pp-input-form {
453
574
  display: flex;
454
- padding: 12px;
575
+ padding: 10px 12px;
455
576
  gap: 8px;
456
577
  border-top: 1px solid ${colors.border};
578
+ align-items: center;
457
579
  }
458
580
 
459
581
  .pp-input {
460
582
  flex: 1;
461
- padding: 10px 14px;
583
+ min-width: 0;
584
+ height: 40px;
585
+ line-height: 40px;
586
+ padding: 0 16px;
462
587
  border: 1px solid ${colors.border};
463
588
  border-radius: 20px;
464
589
  background: ${colors.bg};
@@ -466,6 +591,8 @@ function styles(primaryColor, theme) {
466
591
  font-size: 14px;
467
592
  outline: none;
468
593
  transition: border-color 0.2s;
594
+ box-sizing: border-box;
595
+ margin: 0;
469
596
  }
470
597
 
471
598
  .pp-input:focus {
@@ -479,6 +606,7 @@ function styles(primaryColor, theme) {
479
606
  .pp-send-btn {
480
607
  width: 40px;
481
608
  height: 40px;
609
+ min-width: 40px;
482
610
  border-radius: 50%;
483
611
  background: ${primaryColor};
484
612
  color: white;
@@ -487,7 +615,18 @@ function styles(primaryColor, theme) {
487
615
  display: flex;
488
616
  align-items: center;
489
617
  justify-content: center;
490
- transition: opacity 0.2s;
618
+ transition: opacity 0.2s, transform 0.1s;
619
+ flex-shrink: 0;
620
+ margin: 0;
621
+ padding: 0;
622
+ }
623
+
624
+ .pp-send-btn:not(:disabled):hover {
625
+ transform: scale(1.05);
626
+ }
627
+
628
+ .pp-send-btn:not(:disabled):active {
629
+ transform: scale(0.95);
491
630
  }
492
631
 
493
632
  .pp-send-btn:disabled {
@@ -506,6 +645,7 @@ function styles(primaryColor, theme) {
506
645
  font-size: 11px;
507
646
  color: ${colors.textSecondary};
508
647
  border-top: 1px solid ${colors.border};
648
+ opacity: 0.7;
509
649
  }
510
650
 
511
651
  .pp-footer a {
@@ -534,6 +674,7 @@ function styles(primaryColor, theme) {
534
674
  .pp-attach-btn {
535
675
  width: 40px;
536
676
  height: 40px;
677
+ min-width: 40px;
537
678
  border-radius: 50%;
538
679
  background: transparent;
539
680
  color: ${colors.textSecondary};
@@ -542,6 +683,8 @@ function styles(primaryColor, theme) {
542
683
  display: flex;
543
684
  align-items: center;
544
685
  justify-content: center;
686
+ margin: 0;
687
+ padding: 0;
545
688
  transition: color 0.2s, border-color 0.2s;
546
689
  flex-shrink: 0;
547
690
  }
@@ -662,7 +805,10 @@ function styles(primaryColor, theme) {
662
805
  display: flex;
663
806
  flex-direction: column;
664
807
  gap: 8px;
665
- margin-top: 4px;
808
+ margin-top: 6px;
809
+ max-width: 100%;
810
+ align-items: flex-start;
811
+ flex-shrink: 0;
666
812
  }
667
813
 
668
814
  .pp-attachment {
@@ -673,11 +819,22 @@ function styles(primaryColor, theme) {
673
819
  overflow: hidden;
674
820
  }
675
821
 
822
+ .pp-attachment-image,
823
+ .pp-attachment-video,
824
+ .pp-attachment-audio {
825
+ width: 240px;
826
+ max-width: 100%;
827
+ }
828
+
676
829
  .pp-attachment-image img {
677
- max-width: 200px;
830
+ width: 100% !important;
831
+ height: auto !important;
832
+ max-width: 240px;
678
833
  max-height: 200px;
679
834
  border-radius: 8px;
680
835
  display: block;
836
+ object-fit: cover !important;
837
+ object-position: center;
681
838
  }
682
839
 
683
840
  .pp-attachment-audio {
@@ -687,7 +844,8 @@ function styles(primaryColor, theme) {
687
844
  }
688
845
 
689
846
  .pp-attachment-audio audio {
690
- width: 200px;
847
+ width: 240px;
848
+ max-width: 100%;
691
849
  height: 36px;
692
850
  }
693
851
 
@@ -697,14 +855,18 @@ function styles(primaryColor, theme) {
697
855
  white-space: nowrap;
698
856
  overflow: hidden;
699
857
  text-overflow: ellipsis;
700
- max-width: 200px;
858
+ max-width: 100%;
701
859
  }
702
860
 
703
861
  .pp-attachment-video video {
704
- max-width: 200px;
705
- max-height: 200px;
862
+ width: 100% !important;
863
+ height: auto !important;
864
+ max-width: 240px;
865
+ max-height: none;
706
866
  border-radius: 8px;
707
867
  display: block;
868
+ object-fit: contain !important;
869
+ object-position: center;
708
870
  }
709
871
 
710
872
  .pp-attachment-file {
@@ -1055,34 +1217,665 @@ function styles(primaryColor, theme) {
1055
1217
  margin-left: 4px;
1056
1218
  font-style: italic;
1057
1219
  }
1220
+
1221
+ /* Pre-Chat Form */
1222
+ .pp-prechat {
1223
+ flex: 1;
1224
+ display: flex;
1225
+ flex-direction: column;
1226
+ padding: 24px 20px;
1227
+ overflow-y: auto;
1228
+ }
1229
+
1230
+ .pp-prechat-title {
1231
+ font-size: 18px;
1232
+ font-weight: 600;
1233
+ margin-bottom: 8px;
1234
+ color: ${colors.text};
1235
+ }
1236
+
1237
+ .pp-prechat-subtitle {
1238
+ font-size: 13px;
1239
+ color: ${colors.textSecondary};
1240
+ margin-bottom: 24px;
1241
+ }
1242
+
1243
+ .pp-prechat-tabs {
1244
+ display: flex;
1245
+ gap: 8px;
1246
+ margin-bottom: 20px;
1247
+ }
1248
+
1249
+ .pp-prechat-tab {
1250
+ flex: 1;
1251
+ padding: 10px;
1252
+ border: 1px solid ${colors.border};
1253
+ border-radius: 8px;
1254
+ background: transparent;
1255
+ color: ${colors.textSecondary};
1256
+ font-size: 13px;
1257
+ cursor: pointer;
1258
+ transition: all 0.2s;
1259
+ display: flex;
1260
+ align-items: center;
1261
+ justify-content: center;
1262
+ gap: 6px;
1263
+ }
1264
+
1265
+ .pp-prechat-tab:hover {
1266
+ background: ${colors.bgSecondary};
1267
+ }
1268
+
1269
+ .pp-prechat-tab.active {
1270
+ background: ${primaryColor}15;
1271
+ border-color: ${primaryColor};
1272
+ color: ${primaryColor};
1273
+ }
1274
+
1275
+ .pp-prechat-tab svg {
1276
+ width: 16px;
1277
+ height: 16px;
1278
+ }
1279
+
1280
+ .pp-prechat-field {
1281
+ margin-bottom: 16px;
1282
+ }
1283
+
1284
+ .pp-prechat-label {
1285
+ display: block;
1286
+ font-size: 12px;
1287
+ font-weight: 500;
1288
+ color: ${colors.textSecondary};
1289
+ margin-bottom: 6px;
1290
+ }
1291
+
1292
+ .pp-prechat-input {
1293
+ width: 100%;
1294
+ height: 44px;
1295
+ padding: 0 14px;
1296
+ border: 1px solid ${colors.border};
1297
+ border-radius: 8px;
1298
+ background: ${colors.bg};
1299
+ color: ${colors.text};
1300
+ font-size: 14px;
1301
+ outline: none;
1302
+ transition: border-color 0.2s;
1303
+ box-sizing: border-box;
1304
+ }
1305
+
1306
+ .pp-prechat-input:focus {
1307
+ border-color: ${primaryColor};
1308
+ }
1309
+
1310
+ .pp-prechat-input::placeholder {
1311
+ color: ${colors.textSecondary};
1312
+ }
1313
+
1314
+ .pp-prechat-input.error {
1315
+ border-color: #ef4444;
1316
+ }
1317
+
1318
+ .pp-prechat-error {
1319
+ color: #ef4444;
1320
+ font-size: 12px;
1321
+ margin-top: 4px;
1322
+ }
1323
+
1324
+ .pp-phone-input-wrapper {
1325
+ display: flex;
1326
+ gap: 8px;
1327
+ }
1328
+
1329
+ .pp-country-select {
1330
+ position: relative;
1331
+ }
1332
+
1333
+ .pp-country-btn {
1334
+ display: flex;
1335
+ align-items: center;
1336
+ gap: 6px;
1337
+ height: 44px;
1338
+ padding: 0 10px;
1339
+ border: 1px solid ${colors.border};
1340
+ border-radius: 8px;
1341
+ background: ${colors.bg};
1342
+ color: ${colors.text};
1343
+ font-size: 14px;
1344
+ cursor: pointer;
1345
+ transition: border-color 0.2s;
1346
+ }
1347
+
1348
+ .pp-country-btn:focus {
1349
+ border-color: ${primaryColor};
1350
+ outline: none;
1351
+ }
1352
+
1353
+ .pp-country-flag {
1354
+ font-size: 18px;
1355
+ line-height: 1;
1356
+ }
1357
+
1358
+ .pp-country-code {
1359
+ font-size: 13px;
1360
+ color: ${colors.textSecondary};
1361
+ }
1362
+
1363
+ .pp-country-chevron {
1364
+ width: 12px;
1365
+ height: 12px;
1366
+ color: ${colors.textSecondary};
1367
+ }
1368
+
1369
+ .pp-country-dropdown {
1370
+ position: absolute;
1371
+ top: calc(100% + 4px);
1372
+ left: 0;
1373
+ width: 280px;
1374
+ max-height: 280px;
1375
+ overflow-y: auto;
1376
+ background: ${colors.bg};
1377
+ border: 1px solid ${colors.border};
1378
+ border-radius: 8px;
1379
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
1380
+ z-index: 100;
1381
+ }
1382
+
1383
+ .pp-country-search {
1384
+ position: sticky;
1385
+ top: 0;
1386
+ padding: 8px;
1387
+ background: ${colors.bg};
1388
+ border-bottom: 1px solid ${colors.border};
1389
+ }
1390
+
1391
+ .pp-country-search-input {
1392
+ width: 100%;
1393
+ height: 36px;
1394
+ padding: 0 12px;
1395
+ border: 1px solid ${colors.border};
1396
+ border-radius: 6px;
1397
+ background: ${colors.bgSecondary};
1398
+ color: ${colors.text};
1399
+ font-size: 13px;
1400
+ outline: none;
1401
+ box-sizing: border-box;
1402
+ }
1403
+
1404
+ .pp-country-search-input:focus {
1405
+ border-color: ${primaryColor};
1406
+ }
1407
+
1408
+ .pp-country-list {
1409
+ padding: 4px;
1410
+ }
1411
+
1412
+ .pp-country-option {
1413
+ display: flex;
1414
+ align-items: center;
1415
+ gap: 10px;
1416
+ padding: 10px 12px;
1417
+ cursor: pointer;
1418
+ border-radius: 6px;
1419
+ transition: background 0.15s;
1420
+ }
1421
+
1422
+ .pp-country-option:hover {
1423
+ background: ${colors.bgSecondary};
1424
+ }
1425
+
1426
+ .pp-country-option.selected {
1427
+ background: ${primaryColor}15;
1428
+ }
1429
+
1430
+ .pp-country-name {
1431
+ flex: 1;
1432
+ font-size: 13px;
1433
+ color: ${colors.text};
1434
+ }
1435
+
1436
+ .pp-country-dial {
1437
+ font-size: 12px;
1438
+ color: ${colors.textSecondary};
1439
+ }
1440
+
1441
+ .pp-phone-number-input {
1442
+ flex: 1;
1443
+ }
1444
+
1445
+ .pp-prechat-submit {
1446
+ width: 100%;
1447
+ height: 44px;
1448
+ margin-top: 8px;
1449
+ border: none;
1450
+ border-radius: 8px;
1451
+ background: ${primaryColor};
1452
+ color: white;
1453
+ font-size: 14px;
1454
+ font-weight: 500;
1455
+ cursor: pointer;
1456
+ transition: opacity 0.2s, transform 0.1s;
1457
+ }
1458
+
1459
+ .pp-prechat-submit:hover:not(:disabled) {
1460
+ opacity: 0.9;
1461
+ }
1462
+
1463
+ .pp-prechat-submit:active:not(:disabled) {
1464
+ transform: scale(0.98);
1465
+ }
1466
+
1467
+ .pp-prechat-submit:disabled {
1468
+ opacity: 0.5;
1469
+ cursor: not-allowed;
1470
+ }
1471
+
1472
+ .pp-prechat-skip {
1473
+ width: 100%;
1474
+ padding: 12px;
1475
+ margin-top: 8px;
1476
+ border: none;
1477
+ background: transparent;
1478
+ color: ${colors.textSecondary};
1479
+ font-size: 13px;
1480
+ cursor: pointer;
1481
+ transition: color 0.2s;
1482
+ }
1483
+
1484
+ .pp-prechat-skip:hover {
1485
+ color: ${colors.text};
1486
+ }
1058
1487
  `;
1059
1488
  }
1060
1489
 
1061
- // src/components/ChatWidget.tsx
1490
+ // src/components/PreChatForm.tsx
1491
+ var import_hooks = require("preact/hooks");
1492
+ var import_min = require("libphonenumber-js/min");
1493
+
1494
+ // src/data/countries.ts
1495
+ var countries = [
1496
+ // Europe
1497
+ { code: "FR", name: "France", dialCode: "+33", flag: "\u{1F1EB}\u{1F1F7}" },
1498
+ { code: "DE", name: "Germany", dialCode: "+49", flag: "\u{1F1E9}\u{1F1EA}" },
1499
+ { code: "GB", name: "United Kingdom", dialCode: "+44", flag: "\u{1F1EC}\u{1F1E7}" },
1500
+ { code: "ES", name: "Spain", dialCode: "+34", flag: "\u{1F1EA}\u{1F1F8}" },
1501
+ { code: "IT", name: "Italy", dialCode: "+39", flag: "\u{1F1EE}\u{1F1F9}" },
1502
+ { code: "PT", name: "Portugal", dialCode: "+351", flag: "\u{1F1F5}\u{1F1F9}" },
1503
+ { code: "NL", name: "Netherlands", dialCode: "+31", flag: "\u{1F1F3}\u{1F1F1}" },
1504
+ { code: "BE", name: "Belgium", dialCode: "+32", flag: "\u{1F1E7}\u{1F1EA}" },
1505
+ { code: "CH", name: "Switzerland", dialCode: "+41", flag: "\u{1F1E8}\u{1F1ED}" },
1506
+ { code: "AT", name: "Austria", dialCode: "+43", flag: "\u{1F1E6}\u{1F1F9}" },
1507
+ { code: "SE", name: "Sweden", dialCode: "+46", flag: "\u{1F1F8}\u{1F1EA}" },
1508
+ { code: "NO", name: "Norway", dialCode: "+47", flag: "\u{1F1F3}\u{1F1F4}" },
1509
+ { code: "DK", name: "Denmark", dialCode: "+45", flag: "\u{1F1E9}\u{1F1F0}" },
1510
+ { code: "FI", name: "Finland", dialCode: "+358", flag: "\u{1F1EB}\u{1F1EE}" },
1511
+ { code: "PL", name: "Poland", dialCode: "+48", flag: "\u{1F1F5}\u{1F1F1}" },
1512
+ { code: "CZ", name: "Czech Republic", dialCode: "+420", flag: "\u{1F1E8}\u{1F1FF}" },
1513
+ { code: "GR", name: "Greece", dialCode: "+30", flag: "\u{1F1EC}\u{1F1F7}" },
1514
+ { code: "IE", name: "Ireland", dialCode: "+353", flag: "\u{1F1EE}\u{1F1EA}" },
1515
+ { code: "RO", name: "Romania", dialCode: "+40", flag: "\u{1F1F7}\u{1F1F4}" },
1516
+ { code: "HU", name: "Hungary", dialCode: "+36", flag: "\u{1F1ED}\u{1F1FA}" },
1517
+ // North America
1518
+ { code: "US", name: "United States", dialCode: "+1", flag: "\u{1F1FA}\u{1F1F8}" },
1519
+ { code: "CA", name: "Canada", dialCode: "+1", flag: "\u{1F1E8}\u{1F1E6}" },
1520
+ { code: "MX", name: "Mexico", dialCode: "+52", flag: "\u{1F1F2}\u{1F1FD}" },
1521
+ // South America
1522
+ { code: "BR", name: "Brazil", dialCode: "+55", flag: "\u{1F1E7}\u{1F1F7}" },
1523
+ { code: "AR", name: "Argentina", dialCode: "+54", flag: "\u{1F1E6}\u{1F1F7}" },
1524
+ { code: "CL", name: "Chile", dialCode: "+56", flag: "\u{1F1E8}\u{1F1F1}" },
1525
+ { code: "CO", name: "Colombia", dialCode: "+57", flag: "\u{1F1E8}\u{1F1F4}" },
1526
+ { code: "PE", name: "Peru", dialCode: "+51", flag: "\u{1F1F5}\u{1F1EA}" },
1527
+ // Asia
1528
+ { code: "CN", name: "China", dialCode: "+86", flag: "\u{1F1E8}\u{1F1F3}" },
1529
+ { code: "JP", name: "Japan", dialCode: "+81", flag: "\u{1F1EF}\u{1F1F5}" },
1530
+ { code: "KR", name: "South Korea", dialCode: "+82", flag: "\u{1F1F0}\u{1F1F7}" },
1531
+ { code: "IN", name: "India", dialCode: "+91", flag: "\u{1F1EE}\u{1F1F3}" },
1532
+ { code: "ID", name: "Indonesia", dialCode: "+62", flag: "\u{1F1EE}\u{1F1E9}" },
1533
+ { code: "TH", name: "Thailand", dialCode: "+66", flag: "\u{1F1F9}\u{1F1ED}" },
1534
+ { code: "VN", name: "Vietnam", dialCode: "+84", flag: "\u{1F1FB}\u{1F1F3}" },
1535
+ { code: "MY", name: "Malaysia", dialCode: "+60", flag: "\u{1F1F2}\u{1F1FE}" },
1536
+ { code: "SG", name: "Singapore", dialCode: "+65", flag: "\u{1F1F8}\u{1F1EC}" },
1537
+ { code: "PH", name: "Philippines", dialCode: "+63", flag: "\u{1F1F5}\u{1F1ED}" },
1538
+ { code: "PK", name: "Pakistan", dialCode: "+92", flag: "\u{1F1F5}\u{1F1F0}" },
1539
+ { code: "BD", name: "Bangladesh", dialCode: "+880", flag: "\u{1F1E7}\u{1F1E9}" },
1540
+ // Middle East
1541
+ { code: "AE", name: "United Arab Emirates", dialCode: "+971", flag: "\u{1F1E6}\u{1F1EA}" },
1542
+ { code: "SA", name: "Saudi Arabia", dialCode: "+966", flag: "\u{1F1F8}\u{1F1E6}" },
1543
+ { code: "IL", name: "Israel", dialCode: "+972", flag: "\u{1F1EE}\u{1F1F1}" },
1544
+ { code: "TR", name: "Turkey", dialCode: "+90", flag: "\u{1F1F9}\u{1F1F7}" },
1545
+ { code: "EG", name: "Egypt", dialCode: "+20", flag: "\u{1F1EA}\u{1F1EC}" },
1546
+ // Africa
1547
+ { code: "ZA", name: "South Africa", dialCode: "+27", flag: "\u{1F1FF}\u{1F1E6}" },
1548
+ { code: "NG", name: "Nigeria", dialCode: "+234", flag: "\u{1F1F3}\u{1F1EC}" },
1549
+ { code: "KE", name: "Kenya", dialCode: "+254", flag: "\u{1F1F0}\u{1F1EA}" },
1550
+ { code: "MA", name: "Morocco", dialCode: "+212", flag: "\u{1F1F2}\u{1F1E6}" },
1551
+ { code: "TN", name: "Tunisia", dialCode: "+216", flag: "\u{1F1F9}\u{1F1F3}" },
1552
+ { code: "DZ", name: "Algeria", dialCode: "+213", flag: "\u{1F1E9}\u{1F1FF}" },
1553
+ // Oceania
1554
+ { code: "AU", name: "Australia", dialCode: "+61", flag: "\u{1F1E6}\u{1F1FA}" },
1555
+ { code: "NZ", name: "New Zealand", dialCode: "+64", flag: "\u{1F1F3}\u{1F1FF}" },
1556
+ // Russia & CIS
1557
+ { code: "RU", name: "Russia", dialCode: "+7", flag: "\u{1F1F7}\u{1F1FA}" },
1558
+ { code: "UA", name: "Ukraine", dialCode: "+380", flag: "\u{1F1FA}\u{1F1E6}" }
1559
+ ].sort((a, b) => a.name.localeCompare(b.name));
1560
+ function findCountryByCode(code) {
1561
+ return countries.find((c) => c.code === code.toUpperCase());
1562
+ }
1563
+ var defaultCountry = findCountryByCode("FR");
1564
+
1565
+ // src/components/PreChatForm.tsx
1062
1566
  var import_jsx_runtime = require("preact/jsx-runtime");
1063
- function ChatWidget({ client: client2, config: initialConfig }) {
1064
- const [isOpen, setIsOpen] = (0, import_hooks.useState)(false);
1065
- const [messages, setMessages] = (0, import_hooks.useState)([]);
1066
- const [inputValue, setInputValue] = (0, import_hooks.useState)("");
1067
- const [isTyping, setIsTyping] = (0, import_hooks.useState)(false);
1068
- const [operatorOnline, setOperatorOnline] = (0, import_hooks.useState)(false);
1069
- const [isConnected, setIsConnected] = (0, import_hooks.useState)(false);
1070
- const [unreadCount, setUnreadCount] = (0, import_hooks.useState)(0);
1071
- const [pendingAttachments, setPendingAttachments] = (0, import_hooks.useState)([]);
1072
- const [isUploading, setIsUploading] = (0, import_hooks.useState)(false);
1073
- const [replyingTo, setReplyingTo] = (0, import_hooks.useState)(null);
1074
- const [editingMessage, setEditingMessage] = (0, import_hooks.useState)(null);
1075
- const [editContent, setEditContent] = (0, import_hooks.useState)("");
1076
- const [messageMenu, setMessageMenu] = (0, import_hooks.useState)(null);
1077
- const [isDragging, setIsDragging] = (0, import_hooks.useState)(false);
1078
- const [hoveredMessageId, setHoveredMessageId] = (0, import_hooks.useState)(null);
1079
- const [longPressTimer, setLongPressTimer] = (0, import_hooks.useState)(null);
1080
- const [config, setConfig] = (0, import_hooks.useState)(initialConfig);
1081
- const messagesEndRef = (0, import_hooks.useRef)(null);
1082
- const inputRef = (0, import_hooks.useRef)(null);
1083
- const fileInputRef = (0, import_hooks.useRef)(null);
1084
- const messagesContainerRef = (0, import_hooks.useRef)(null);
1567
+ var EmailIcon = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1568
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" }),
1569
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M22 7l-10 7L2 7" })
1570
+ ] });
1571
+ 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" }) });
1572
+ 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" }) });
1573
+ function isValidEmail(email) {
1574
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
1575
+ }
1576
+ function PreChatForm({ client: client2, config, onComplete, onSkip }) {
1577
+ const showEmailOnly = config.fields === "email-only";
1578
+ const showPhoneOnly = config.fields === "phone-only";
1579
+ const showBoth = config.fields === "email-and-phone";
1580
+ const showChoice = config.fields === "email-or-phone";
1581
+ const getDefaultTab = () => {
1582
+ if (showPhoneOnly) return "phone";
1583
+ return "email";
1584
+ };
1585
+ const [activeTab, setActiveTab] = (0, import_hooks.useState)(getDefaultTab());
1586
+ const [email, setEmail] = (0, import_hooks.useState)("");
1587
+ const [phone, setPhone] = (0, import_hooks.useState)("");
1588
+ const [selectedCountry, setSelectedCountry] = (0, import_hooks.useState)(defaultCountry);
1589
+ const [isCountryDropdownOpen, setIsCountryDropdownOpen] = (0, import_hooks.useState)(false);
1590
+ const [countrySearch, setCountrySearch] = (0, import_hooks.useState)("");
1591
+ const [emailError, setEmailError] = (0, import_hooks.useState)("");
1592
+ const [phoneError, setPhoneError] = (0, import_hooks.useState)("");
1593
+ const [isSubmitting, setIsSubmitting] = (0, import_hooks.useState)(false);
1594
+ const countryDropdownRef = (0, import_hooks.useRef)(null);
1595
+ const searchInputRef = (0, import_hooks.useRef)(null);
1596
+ (0, import_hooks.useEffect)(() => {
1597
+ const handleClickOutside = (e) => {
1598
+ if (countryDropdownRef.current && !countryDropdownRef.current.contains(e.target)) {
1599
+ setIsCountryDropdownOpen(false);
1600
+ }
1601
+ };
1602
+ document.addEventListener("mousedown", handleClickOutside);
1603
+ return () => document.removeEventListener("mousedown", handleClickOutside);
1604
+ }, []);
1085
1605
  (0, import_hooks.useEffect)(() => {
1606
+ if (isCountryDropdownOpen && searchInputRef.current) {
1607
+ searchInputRef.current.focus();
1608
+ }
1609
+ }, [isCountryDropdownOpen]);
1610
+ const filteredCountries = countries.filter(
1611
+ (c) => c.name.toLowerCase().includes(countrySearch.toLowerCase()) || c.dialCode.includes(countrySearch) || c.code.toLowerCase().includes(countrySearch.toLowerCase())
1612
+ );
1613
+ const handleCountrySelect = (country) => {
1614
+ setSelectedCountry(country);
1615
+ setIsCountryDropdownOpen(false);
1616
+ setCountrySearch("");
1617
+ };
1618
+ const formatPhoneForDisplay = (value) => {
1619
+ const digits = value.replace(/\D/g, "");
1620
+ return digits;
1621
+ };
1622
+ const handlePhoneChange = (e) => {
1623
+ const target = e.target;
1624
+ const formatted = formatPhoneForDisplay(target.value);
1625
+ setPhone(formatted);
1626
+ setPhoneError("");
1627
+ };
1628
+ const getFullPhoneNumber = () => {
1629
+ if (!phone) return "";
1630
+ return `${selectedCountry.dialCode}${phone}`;
1631
+ };
1632
+ const validateForm = () => {
1633
+ let valid = true;
1634
+ if (showEmailOnly || showBoth) {
1635
+ if (!email.trim()) {
1636
+ setEmailError("Email is required");
1637
+ valid = false;
1638
+ } else if (!isValidEmail(email)) {
1639
+ setEmailError("Please enter a valid email");
1640
+ valid = false;
1641
+ }
1642
+ }
1643
+ if (showPhoneOnly || showBoth) {
1644
+ const fullPhone = getFullPhoneNumber();
1645
+ if (!phone.trim()) {
1646
+ setPhoneError("Phone number is required");
1647
+ valid = false;
1648
+ } else if (!(0, import_min.isValidPhoneNumber)(fullPhone, selectedCountry.code)) {
1649
+ setPhoneError("Please enter a valid phone number");
1650
+ valid = false;
1651
+ }
1652
+ }
1653
+ if (showChoice) {
1654
+ if (activeTab === "email") {
1655
+ if (!email.trim()) {
1656
+ setEmailError("Email is required");
1657
+ valid = false;
1658
+ } else if (!isValidEmail(email)) {
1659
+ setEmailError("Please enter a valid email");
1660
+ valid = false;
1661
+ }
1662
+ } else {
1663
+ const fullPhone = getFullPhoneNumber();
1664
+ if (!phone.trim()) {
1665
+ setPhoneError("Phone number is required");
1666
+ valid = false;
1667
+ } else if (!(0, import_min.isValidPhoneNumber)(fullPhone, selectedCountry.code)) {
1668
+ setPhoneError("Please enter a valid phone number");
1669
+ valid = false;
1670
+ }
1671
+ }
1672
+ }
1673
+ return valid;
1674
+ };
1675
+ const handleSubmit = async (e) => {
1676
+ e.preventDefault();
1677
+ if (!validateForm()) return;
1678
+ setIsSubmitting(true);
1679
+ try {
1680
+ const data = {};
1681
+ if (showEmailOnly || showBoth || showChoice && activeTab === "email") {
1682
+ data.email = email.trim();
1683
+ }
1684
+ if (showPhoneOnly || showBoth || showChoice && activeTab === "phone") {
1685
+ const fullPhone = getFullPhoneNumber();
1686
+ const parsed = (0, import_min.parsePhoneNumber)(fullPhone, selectedCountry.code);
1687
+ if (parsed) {
1688
+ data.phone = parsed.format("E.164");
1689
+ data.phoneCountry = selectedCountry.code;
1690
+ }
1691
+ }
1692
+ await client2.submitPreChat(data);
1693
+ onComplete();
1694
+ } catch (err) {
1695
+ console.error("[PreChatForm] Submit error:", err);
1696
+ if (activeTab === "email" || showEmailOnly || showBoth) {
1697
+ setEmailError("Something went wrong. Please try again.");
1698
+ } else {
1699
+ setPhoneError("Something went wrong. Please try again.");
1700
+ }
1701
+ } finally {
1702
+ setIsSubmitting(false);
1703
+ }
1704
+ };
1705
+ const renderEmailField = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-prechat-field", children: [
1706
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { class: "pp-prechat-label", children: "Email address" }),
1707
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1708
+ "input",
1709
+ {
1710
+ type: "email",
1711
+ class: `pp-prechat-input ${emailError ? "error" : ""}`,
1712
+ placeholder: "you@example.com",
1713
+ value: email,
1714
+ onInput: (e) => {
1715
+ setEmail(e.target.value);
1716
+ setEmailError("");
1717
+ }
1718
+ }
1719
+ ),
1720
+ emailError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-prechat-error", children: emailError })
1721
+ ] });
1722
+ const renderPhoneField = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-prechat-field", children: [
1723
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { class: "pp-prechat-label", children: "Phone number" }),
1724
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-phone-input-wrapper", children: [
1725
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-country-select", ref: countryDropdownRef, children: [
1726
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1727
+ "button",
1728
+ {
1729
+ type: "button",
1730
+ class: "pp-country-btn",
1731
+ onClick: () => setIsCountryDropdownOpen(!isCountryDropdownOpen),
1732
+ children: [
1733
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-country-flag", children: selectedCountry.flag }),
1734
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-country-code", children: selectedCountry.dialCode }),
1735
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronIcon, {})
1736
+ ]
1737
+ }
1738
+ ),
1739
+ isCountryDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-country-dropdown", children: [
1740
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-country-search", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1741
+ "input",
1742
+ {
1743
+ ref: searchInputRef,
1744
+ type: "text",
1745
+ class: "pp-country-search-input",
1746
+ placeholder: "Search country...",
1747
+ value: countrySearch,
1748
+ onInput: (e) => setCountrySearch(e.target.value)
1749
+ }
1750
+ ) }),
1751
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-country-list", children: filteredCountries.map((country) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1752
+ "div",
1753
+ {
1754
+ class: `pp-country-option ${country.code === selectedCountry.code ? "selected" : ""}`,
1755
+ onClick: () => handleCountrySelect(country),
1756
+ children: [
1757
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-country-flag", children: country.flag }),
1758
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-country-name", children: country.name }),
1759
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-country-dial", children: country.dialCode })
1760
+ ]
1761
+ },
1762
+ country.code
1763
+ )) })
1764
+ ] })
1765
+ ] }),
1766
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1767
+ "input",
1768
+ {
1769
+ type: "tel",
1770
+ class: `pp-prechat-input pp-phone-number-input ${phoneError ? "error" : ""}`,
1771
+ placeholder: "612 345 678",
1772
+ value: phone,
1773
+ onInput: handlePhoneChange
1774
+ }
1775
+ )
1776
+ ] }),
1777
+ phoneError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-prechat-error", children: phoneError })
1778
+ ] });
1779
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-prechat", children: [
1780
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { class: "pp-prechat-title", children: "How can we reach you?" }),
1781
+ /* @__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." }),
1782
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { onSubmit: handleSubmit, children: [
1783
+ showChoice && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-prechat-tabs", children: [
1784
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1785
+ "button",
1786
+ {
1787
+ type: "button",
1788
+ class: `pp-prechat-tab ${activeTab === "email" ? "active" : ""}`,
1789
+ onClick: () => {
1790
+ setActiveTab("email");
1791
+ setPhoneError("");
1792
+ },
1793
+ children: [
1794
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmailIcon, {}),
1795
+ "Email"
1796
+ ]
1797
+ }
1798
+ ),
1799
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1800
+ "button",
1801
+ {
1802
+ type: "button",
1803
+ class: `pp-prechat-tab ${activeTab === "phone" ? "active" : ""}`,
1804
+ onClick: () => {
1805
+ setActiveTab("phone");
1806
+ setEmailError("");
1807
+ },
1808
+ children: [
1809
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PhoneIcon, {}),
1810
+ "Phone"
1811
+ ]
1812
+ }
1813
+ )
1814
+ ] }),
1815
+ showEmailOnly && renderEmailField(),
1816
+ showPhoneOnly && renderPhoneField(),
1817
+ showBoth && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1818
+ renderEmailField(),
1819
+ renderPhoneField()
1820
+ ] }),
1821
+ showChoice && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1822
+ activeTab === "email" && renderEmailField(),
1823
+ activeTab === "phone" && renderPhoneField()
1824
+ ] }),
1825
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "submit", class: "pp-prechat-submit", disabled: isSubmitting, children: isSubmitting ? "Submitting..." : "Start chatting" }),
1826
+ !config.required && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", class: "pp-prechat-skip", onClick: onSkip, children: "Skip for now" })
1827
+ ] })
1828
+ ] });
1829
+ }
1830
+
1831
+ // src/components/ChatWidget.tsx
1832
+ var import_jsx_runtime2 = require("preact/jsx-runtime");
1833
+ function formatDateSeparator(date) {
1834
+ const now = /* @__PURE__ */ new Date();
1835
+ const messageDate = new Date(date);
1836
+ const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
1837
+ const msgDay = new Date(messageDate.getFullYear(), messageDate.getMonth(), messageDate.getDate());
1838
+ const diffDays = Math.floor((today.getTime() - msgDay.getTime()) / (1e3 * 60 * 60 * 24));
1839
+ if (diffDays === 0) return "Today";
1840
+ if (diffDays === 1) return "Yesterday";
1841
+ return messageDate.toLocaleDateString("en-US", {
1842
+ month: "short",
1843
+ day: "numeric",
1844
+ year: messageDate.getFullYear() !== now.getFullYear() ? "numeric" : void 0
1845
+ });
1846
+ }
1847
+ function getDateKey(date) {
1848
+ const d = new Date(date);
1849
+ return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
1850
+ }
1851
+ function ChatWidget({ client: client2, config: initialConfig }) {
1852
+ const [isOpen, setIsOpen] = (0, import_hooks2.useState)(false);
1853
+ const [messages, setMessages] = (0, import_hooks2.useState)([]);
1854
+ const [inputValue, setInputValue] = (0, import_hooks2.useState)("");
1855
+ const [isTyping, setIsTyping] = (0, import_hooks2.useState)(false);
1856
+ const [operatorOnline, setOperatorOnline] = (0, import_hooks2.useState)(false);
1857
+ const [isConnected, setIsConnected] = (0, import_hooks2.useState)(false);
1858
+ const [unreadCount, setUnreadCount] = (0, import_hooks2.useState)(0);
1859
+ const [pendingAttachments, setPendingAttachments] = (0, import_hooks2.useState)([]);
1860
+ const [isUploading, setIsUploading] = (0, import_hooks2.useState)(false);
1861
+ const [replyingTo, setReplyingTo] = (0, import_hooks2.useState)(null);
1862
+ const [editingMessage, setEditingMessage] = (0, import_hooks2.useState)(null);
1863
+ const [editContent, setEditContent] = (0, import_hooks2.useState)("");
1864
+ const [messageMenu, setMessageMenu] = (0, import_hooks2.useState)(null);
1865
+ const [isDragging, setIsDragging] = (0, import_hooks2.useState)(false);
1866
+ const [hoveredMessageId, setHoveredMessageId] = (0, import_hooks2.useState)(null);
1867
+ const [longPressTimer, setLongPressTimer] = (0, import_hooks2.useState)(null);
1868
+ const [swipedMessageId, setSwipedMessageId] = (0, import_hooks2.useState)(null);
1869
+ const [swipeOffset, setSwipeOffset] = (0, import_hooks2.useState)(0);
1870
+ const touchStartRef = (0, import_hooks2.useRef)(null);
1871
+ const [config, setConfig] = (0, import_hooks2.useState)(initialConfig);
1872
+ const [preChatForm, setPreChatForm] = (0, import_hooks2.useState)(void 0);
1873
+ const [preChatSkipped, setPreChatSkipped] = (0, import_hooks2.useState)(false);
1874
+ const messagesEndRef = (0, import_hooks2.useRef)(null);
1875
+ const inputRef = (0, import_hooks2.useRef)(null);
1876
+ const fileInputRef = (0, import_hooks2.useRef)(null);
1877
+ const messagesContainerRef = (0, import_hooks2.useRef)(null);
1878
+ (0, import_hooks2.useEffect)(() => {
1086
1879
  const unsubOpen = client2.on("openChange", setIsOpen);
1087
1880
  const unsubMessage = client2.on("message", () => {
1088
1881
  setMessages([...client2.getMessages()]);
@@ -1098,6 +1891,10 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1098
1891
  setMessages(client2.getMessages());
1099
1892
  setOperatorOnline(client2.getSession()?.operatorOnline ?? false);
1100
1893
  setConfig(client2.getConfig());
1894
+ setPreChatForm(client2.getSession()?.preChatForm);
1895
+ });
1896
+ const unsubPreChat = client2.on("preChatCompleted", () => {
1897
+ setPreChatForm((prev) => prev ? { ...prev, completed: true } : prev);
1101
1898
  });
1102
1899
  const unsubConfig = client2.on("configUpdate", () => {
1103
1900
  setConfig(client2.getConfig());
@@ -1107,6 +1904,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1107
1904
  setMessages(client2.getMessages());
1108
1905
  setOperatorOnline(client2.getSession()?.operatorOnline ?? false);
1109
1906
  setConfig(client2.getConfig());
1907
+ setPreChatForm(client2.getSession()?.preChatForm);
1110
1908
  }
1111
1909
  return () => {
1112
1910
  unsubOpen();
@@ -1114,15 +1912,16 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1114
1912
  unsubTyping();
1115
1913
  unsubPresence();
1116
1914
  unsubConnect();
1915
+ unsubPreChat();
1117
1916
  unsubConfig();
1118
1917
  };
1119
1918
  }, [client2]);
1120
- (0, import_hooks.useEffect)(() => {
1919
+ (0, import_hooks2.useEffect)(() => {
1121
1920
  if (isOpen) {
1122
1921
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
1123
1922
  }
1124
1923
  }, [messages, isOpen]);
1125
- (0, import_hooks.useEffect)(() => {
1924
+ (0, import_hooks2.useEffect)(() => {
1126
1925
  if (isOpen) {
1127
1926
  setTimeout(() => {
1128
1927
  messagesEndRef.current?.scrollIntoView({ behavior: "auto" });
@@ -1131,7 +1930,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1131
1930
  setUnreadCount(0);
1132
1931
  }
1133
1932
  }, [isOpen]);
1134
- (0, import_hooks.useEffect)(() => {
1933
+ (0, import_hooks2.useEffect)(() => {
1135
1934
  if (!isOpen && messages.length > 0) {
1136
1935
  const unread = messages.filter(
1137
1936
  (msg) => msg.sender !== "visitor" && msg.status !== "read"
@@ -1139,7 +1938,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1139
1938
  setUnreadCount(unread);
1140
1939
  }
1141
1940
  }, [messages, isOpen]);
1142
- const markMessagesAsRead = (0, import_hooks.useCallback)(() => {
1941
+ const markMessagesAsRead = (0, import_hooks2.useCallback)(() => {
1143
1942
  if (!isOpen || !isConnected) return;
1144
1943
  const unreadMessages = messages.filter(
1145
1944
  (msg) => msg.sender !== "visitor" && msg.status !== "read"
@@ -1149,14 +1948,14 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1149
1948
  client2.sendReadStatus(messageIds, "read");
1150
1949
  }
1151
1950
  }, [isOpen, isConnected, messages, client2]);
1152
- (0, import_hooks.useEffect)(() => {
1951
+ (0, import_hooks2.useEffect)(() => {
1153
1952
  if (!isOpen || !isConnected) return;
1154
1953
  const timer = setTimeout(() => {
1155
1954
  markMessagesAsRead();
1156
1955
  }, 1e3);
1157
1956
  return () => clearTimeout(timer);
1158
1957
  }, [isOpen, isConnected, messages, markMessagesAsRead]);
1159
- (0, import_hooks.useEffect)(() => {
1958
+ (0, import_hooks2.useEffect)(() => {
1160
1959
  const handleVisibilityChange = () => {
1161
1960
  if (document.visibilityState === "visible" && isOpen) {
1162
1961
  markMessagesAsRead();
@@ -1165,7 +1964,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1165
1964
  document.addEventListener("visibilitychange", handleVisibilityChange);
1166
1965
  return () => document.removeEventListener("visibilitychange", handleVisibilityChange);
1167
1966
  }, [isOpen, markMessagesAsRead]);
1168
- (0, import_hooks.useEffect)(() => {
1967
+ (0, import_hooks2.useEffect)(() => {
1169
1968
  const unsubRead = client2.on(
1170
1969
  "read",
1171
1970
  () => {
@@ -1304,26 +2103,43 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1304
2103
  y: mouseEvent.clientY
1305
2104
  });
1306
2105
  };
1307
- const handleTouchStart = (message) => {
1308
- const timer = setTimeout(() => {
1309
- if (navigator.vibrate) navigator.vibrate(50);
1310
- setMessageMenu({
1311
- message,
1312
- x: window.innerWidth / 2 - 60,
1313
- // Center horizontally
1314
- y: window.innerHeight / 2 - 50
1315
- // Center vertically
1316
- });
1317
- }, 500);
1318
- setLongPressTimer(timer);
2106
+ const handleTouchStart = (e, message) => {
2107
+ const touch = e.touches[0];
2108
+ touchStartRef.current = { x: touch.clientX, y: touch.clientY, time: Date.now() };
2109
+ if (swipedMessageId && swipedMessageId !== message.id) {
2110
+ setSwipedMessageId(null);
2111
+ setSwipeOffset(0);
2112
+ }
1319
2113
  };
1320
- const handleTouchEnd = () => {
1321
- if (longPressTimer) {
1322
- clearTimeout(longPressTimer);
1323
- setLongPressTimer(null);
2114
+ const handleTouchMove = (e, message) => {
2115
+ if (!touchStartRef.current) return;
2116
+ const touch = e.touches[0];
2117
+ const deltaX = touch.clientX - touchStartRef.current.x;
2118
+ const deltaY = touch.clientY - touchStartRef.current.y;
2119
+ if (Math.abs(deltaY) > Math.abs(deltaX)) return;
2120
+ if (deltaX < 0) {
2121
+ const offset = Math.max(deltaX, -100);
2122
+ setSwipeOffset(offset);
2123
+ setSwipedMessageId(message.id);
1324
2124
  }
1325
2125
  };
1326
- (0, import_hooks.useEffect)(() => {
2126
+ const handleTouchEnd = (message) => {
2127
+ if (!touchStartRef.current) return;
2128
+ const elapsed = Date.now() - touchStartRef.current.time;
2129
+ if (swipeOffset < -50 || swipeOffset < -20 && elapsed < 200) {
2130
+ setSwipeOffset(-80);
2131
+ if (navigator.vibrate) navigator.vibrate(30);
2132
+ } else {
2133
+ setSwipeOffset(0);
2134
+ setSwipedMessageId(null);
2135
+ }
2136
+ touchStartRef.current = null;
2137
+ };
2138
+ const resetSwipe = () => {
2139
+ setSwipedMessageId(null);
2140
+ setSwipeOffset(0);
2141
+ };
2142
+ (0, import_hooks2.useEffect)(() => {
1327
2143
  if (!messageMenu) return;
1328
2144
  const handleClickOutside = () => setMessageMenu(null);
1329
2145
  document.addEventListener("click", handleClickOutside);
@@ -1339,7 +2155,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1339
2155
  }, 1500);
1340
2156
  }
1341
2157
  };
1342
- const dragCounterRef = (0, import_hooks.useRef)(0);
2158
+ const dragCounterRef = (0, import_hooks2.useRef)(0);
1343
2159
  const handleDragEnter = (e) => {
1344
2160
  e.preventDefault();
1345
2161
  e.stopPropagation();
@@ -1415,22 +2231,24 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1415
2231
  const theme = getTheme(config.theme ?? "auto");
1416
2232
  const primaryColor = config.primaryColor ?? "#6366f1";
1417
2233
  const actionIconColor = theme === "dark" ? "#9ca3af" : "#6b7280";
1418
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_preact.Fragment, { children: [
1419
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: styles(primaryColor, theme) }),
1420
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2234
+ const shouldShowPreChat = preChatForm && preChatForm.enabled && !preChatForm.completed && !preChatSkipped && // Before first message: show immediately
2235
+ (preChatForm.timing === "before-first-message" && messages.length === 0 || preChatForm.timing === "after-first-message" && messages.some((m) => m.sender === "visitor"));
2236
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_preact.Fragment, { children: [
2237
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: styles(primaryColor, theme) }),
2238
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1421
2239
  "button",
1422
2240
  {
1423
2241
  class: `pp-toggle pp-${position}`,
1424
2242
  onClick: () => client2.toggleOpen(),
1425
2243
  "aria-label": isOpen ? "Close chat" : "Open chat",
1426
2244
  children: [
1427
- isOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CloseIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChatIcon, {}),
1428
- !isOpen && unreadCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-unread-badge", children: unreadCount > 9 ? "9+" : unreadCount }),
1429
- !isOpen && unreadCount === 0 && operatorOnline && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-online-dot" })
2245
+ isOpen ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CloseIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChatIcon, {}),
2246
+ !isOpen && unreadCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-unread-badge", children: unreadCount > 9 ? "9+" : unreadCount }),
2247
+ !isOpen && unreadCount === 0 && operatorOnline && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-online-dot" })
1430
2248
  ]
1431
2249
  }
1432
2250
  ),
1433
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2251
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1434
2252
  "div",
1435
2253
  {
1436
2254
  class: `pp-window pp-${position} pp-theme-${theme} ${isDragging ? "pp-dragging" : ""}`,
@@ -1439,39 +2257,55 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1439
2257
  onDragLeave: handleDragLeave,
1440
2258
  onDrop: handleDrop,
1441
2259
  children: [
1442
- isDragging && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-drop-overlay", children: [
1443
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-drop-icon", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AttachIcon, {}) }),
1444
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-drop-text", children: "Drop files to upload" })
2260
+ isDragging && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-drop-overlay", children: [
2261
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-drop-icon", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AttachIcon, {}) }),
2262
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-drop-text", children: "Drop files to upload" })
1445
2263
  ] }),
1446
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-header", children: [
1447
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-header-info", children: [
1448
- config.operatorAvatar && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: config.operatorAvatar, alt: "", class: "pp-avatar" }),
1449
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
1450
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-header-title", children: config.operatorName ?? "Support" }),
1451
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-header-status", children: operatorOnline ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1452
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-status-dot pp-online" }),
2264
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-header", children: [
2265
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-header-info", children: [
2266
+ config.operatorAvatar && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { src: config.operatorAvatar, alt: "", class: "pp-avatar" }),
2267
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
2268
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-header-title", children: config.operatorName ?? "Support" }),
2269
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-header-status", children: operatorOnline ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2270
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-status-dot pp-online" }),
1453
2271
  " Online"
1454
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1455
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-status-dot" }),
2272
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2273
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-status-dot" }),
1456
2274
  " Away"
1457
2275
  ] }) })
1458
2276
  ] })
1459
2277
  ] }),
1460
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2278
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1461
2279
  "button",
1462
2280
  {
1463
2281
  class: "pp-close-btn",
1464
2282
  onClick: () => client2.setOpen(false),
1465
2283
  "aria-label": "Close chat",
1466
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CloseIcon, {})
2284
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CloseIcon, {})
1467
2285
  }
1468
2286
  )
1469
2287
  ] }),
1470
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-messages", ref: messagesContainerRef, children: [
1471
- config.welcomeMessage && messages.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-welcome", children: config.welcomeMessage }),
1472
- messages.map((msg) => {
2288
+ shouldShowPreChat && preChatForm && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2289
+ PreChatForm,
2290
+ {
2291
+ client: client2,
2292
+ config: preChatForm,
2293
+ onComplete: () => {
2294
+ setPreChatForm((prev) => prev ? { ...prev, completed: true } : prev);
2295
+ },
2296
+ onSkip: () => {
2297
+ setPreChatSkipped(true);
2298
+ }
2299
+ }
2300
+ ),
2301
+ !shouldShowPreChat && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-messages", ref: messagesContainerRef, onClick: () => swipedMessageId && resetSwipe(), children: [
2302
+ config.welcomeMessage && messages.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-welcome", children: config.welcomeMessage }),
2303
+ messages.map((msg, index) => {
1473
2304
  const isDeleted = !!msg.deletedAt;
1474
2305
  const isEdited = !!msg.editedAt;
2306
+ const msgDate = new Date(msg.timestamp);
2307
+ const prevMsg = index > 0 ? messages[index - 1] : null;
2308
+ const showDateSeparator = !prevMsg || getDateKey(new Date(prevMsg.timestamp)) !== getDateKey(msgDate);
1475
2309
  let replyData = null;
1476
2310
  if (msg.replyTo) {
1477
2311
  if (typeof msg.replyTo === "object") {
@@ -1493,123 +2327,168 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1493
2327
  }
1494
2328
  const isHovered = hoveredMessageId === msg.id;
1495
2329
  const showActions = isHovered && !isDeleted;
1496
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1497
- "div",
1498
- {
1499
- id: `pp-msg-${msg.id}`,
1500
- class: `pp-message pp-message-${msg.sender} ${isDeleted ? "pp-message-deleted" : ""}`,
1501
- onContextMenu: (e) => handleMessageContextMenu(e, msg),
1502
- onMouseEnter: () => setHoveredMessageId(msg.id),
1503
- onMouseLeave: () => setHoveredMessageId(null),
1504
- onTouchStart: () => handleTouchStart(msg),
1505
- onTouchEnd: handleTouchEnd,
1506
- onTouchCancel: handleTouchEnd,
1507
- children: [
1508
- showActions && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: `pp-message-actions ${msg.sender === "visitor" ? "pp-actions-left" : "pp-actions-right"}`, children: [
1509
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2330
+ const isSwiped = swipedMessageId === msg.id;
2331
+ const msgSwipeOffset = isSwiped ? swipeOffset : 0;
2332
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_preact.Fragment, { children: [
2333
+ showDateSeparator && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-date-separator", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: formatDateSeparator(msgDate) }) }),
2334
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: `pp-message-swipe-container ${msg.sender === "visitor" ? "pp-swipe-left" : "pp-swipe-right"}`, children: [
2335
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-swipe-actions", children: [
2336
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2337
+ "button",
2338
+ {
2339
+ class: "pp-swipe-action pp-swipe-reply",
2340
+ onClick: () => {
2341
+ handleReply(msg);
2342
+ resetSwipe();
2343
+ },
2344
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReplyIcon, { color: "#fff" })
2345
+ }
2346
+ ),
2347
+ msg.sender === "visitor" && !isDeleted && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2348
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1510
2349
  "button",
1511
2350
  {
1512
- class: "pp-action-btn",
1513
- onClick: () => handleReply(msg),
1514
- title: "Reply",
1515
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReplyIcon, { color: actionIconColor })
2351
+ class: "pp-swipe-action pp-swipe-edit",
2352
+ onClick: () => {
2353
+ handleStartEdit(msg);
2354
+ resetSwipe();
2355
+ },
2356
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EditIcon, { color: "#fff" })
1516
2357
  }
1517
2358
  ),
1518
- msg.sender === "visitor" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1519
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1520
- "button",
2359
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2360
+ "button",
2361
+ {
2362
+ class: "pp-swipe-action pp-swipe-delete",
2363
+ onClick: () => {
2364
+ handleDelete(msg);
2365
+ resetSwipe();
2366
+ },
2367
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DeleteIcon, { color: "#fff" })
2368
+ }
2369
+ )
2370
+ ] })
2371
+ ] }),
2372
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2373
+ "div",
2374
+ {
2375
+ id: `pp-msg-${msg.id}`,
2376
+ class: `pp-message pp-message-${msg.sender} ${isDeleted ? "pp-message-deleted" : ""}`,
2377
+ style: { transform: `translateX(${msgSwipeOffset}px)`, transition: touchStartRef.current ? "none" : "transform 0.2s ease-out" },
2378
+ onContextMenu: (e) => handleMessageContextMenu(e, msg),
2379
+ onMouseEnter: () => setHoveredMessageId(msg.id),
2380
+ onMouseLeave: () => setHoveredMessageId(null),
2381
+ onTouchStart: (e) => handleTouchStart(e, msg),
2382
+ onTouchMove: (e) => handleTouchMove(e, msg),
2383
+ onTouchEnd: () => handleTouchEnd(msg),
2384
+ onTouchCancel: () => handleTouchEnd(msg),
2385
+ children: [
2386
+ showActions && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: `pp-message-actions ${msg.sender === "visitor" ? "pp-actions-left" : "pp-actions-right"}`, children: [
2387
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2388
+ "button",
2389
+ {
2390
+ class: "pp-action-btn",
2391
+ onClick: () => handleReply(msg),
2392
+ title: "Reply",
2393
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReplyIcon, { color: actionIconColor })
2394
+ }
2395
+ ),
2396
+ msg.sender === "visitor" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2397
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2398
+ "button",
2399
+ {
2400
+ class: "pp-action-btn",
2401
+ onClick: () => handleStartEdit(msg),
2402
+ title: "Edit",
2403
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EditIcon, { color: actionIconColor })
2404
+ }
2405
+ ),
2406
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2407
+ "button",
2408
+ {
2409
+ class: "pp-action-btn pp-action-delete",
2410
+ onClick: () => handleDelete(msg),
2411
+ title: "Delete",
2412
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DeleteIcon, { color: actionIconColor })
2413
+ }
2414
+ )
2415
+ ] })
2416
+ ] }),
2417
+ replyData && (replyData.content || replyData.hasAttachment) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2418
+ "div",
1521
2419
  {
1522
- class: "pp-action-btn",
1523
- onClick: () => handleStartEdit(msg),
1524
- title: "Edit",
1525
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditIcon, { color: actionIconColor })
2420
+ class: "pp-reply-quote pp-reply-quote-clickable",
2421
+ onClick: () => scrollToMessage(replyData.id),
2422
+ role: "button",
2423
+ tabIndex: 0,
2424
+ onKeyDown: (e) => e.key === "Enter" && scrollToMessage(replyData.id),
2425
+ children: [
2426
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-reply-sender", children: replyData.sender === "visitor" ? "You" : "Support" }),
2427
+ /* @__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: [
2428
+ replyData.hasAttachment && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-reply-attachment-icon", children: replyData.attachmentType?.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
2429
+ replyData.content ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2430
+ (replyData.content || "").slice(0, 50),
2431
+ (replyData.content || "").length > 50 ? "..." : ""
2432
+ ] }) : replyData.attachmentType?.startsWith("image/") ? "Photo" : "File"
2433
+ ] }) })
2434
+ ]
1526
2435
  }
1527
2436
  ),
1528
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1529
- "button",
1530
- {
1531
- class: "pp-action-btn pp-action-delete",
1532
- onClick: () => handleDelete(msg),
1533
- title: "Delete",
1534
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DeleteIcon, { color: actionIconColor })
1535
- }
1536
- )
1537
- ] })
1538
- ] }),
1539
- replyData && (replyData.content || replyData.hasAttachment) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1540
- "div",
1541
- {
1542
- class: "pp-reply-quote pp-reply-quote-clickable",
1543
- onClick: () => scrollToMessage(replyData.id),
1544
- role: "button",
1545
- tabIndex: 0,
1546
- onKeyDown: (e) => e.key === "Enter" && scrollToMessage(replyData.id),
1547
- children: [
1548
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-reply-sender", children: replyData.sender === "visitor" ? "You" : "Support" }),
1549
- /* @__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: [
1550
- replyData.hasAttachment && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-reply-attachment-icon", children: replyData.attachmentType?.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
1551
- replyData.content ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1552
- (replyData.content || "").slice(0, 50),
1553
- (replyData.content || "").length > 50 ? "..." : ""
1554
- ] }) : replyData.attachmentType?.startsWith("image/") ? "Photo" : "File"
1555
- ] }) })
1556
- ]
1557
- }
1558
- ),
1559
- isDeleted ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-message-content pp-deleted-content", children: [
1560
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-deleted-icon", children: "\u{1F5D1}\uFE0F" }),
1561
- " Message deleted"
1562
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1563
- msg.content && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-message-content", children: msg.content }),
1564
- 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)) })
1565
- ] }),
1566
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-message-time", children: [
1567
- formatTime(msg.timestamp),
1568
- isEdited && !isDeleted && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-edited-badge", children: "edited" }),
1569
- msg.sender === "ai" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-ai-badge", children: "AI" }),
1570
- 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 }) })
1571
- ] })
1572
- ]
1573
- },
1574
- msg.id
1575
- );
2437
+ isDeleted ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-message-content pp-deleted-content", children: [
2438
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-deleted-icon", children: "\u{1F5D1}\uFE0F" }),
2439
+ " Message deleted"
2440
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2441
+ msg.content && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-message-content", children: msg.content }),
2442
+ msg.attachments && msg.attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-message-attachments", children: msg.attachments.map((att) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AttachmentDisplay, { attachment: att }, att.id)) })
2443
+ ] }),
2444
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-message-time", children: [
2445
+ formatTime(msg.timestamp),
2446
+ isEdited && !isDeleted && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-edited-badge", children: "edited" }),
2447
+ msg.sender === "ai" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-ai-badge", children: "AI" }),
2448
+ msg.sender === "visitor" && !isDeleted && /* @__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 }) })
2449
+ ] })
2450
+ ]
2451
+ }
2452
+ )
2453
+ ] })
2454
+ ] }, msg.id);
1576
2455
  }),
1577
- isTyping && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-message pp-message-operator pp-typing", children: [
1578
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {}),
1579
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {}),
1580
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {})
2456
+ isTyping && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-message pp-message-operator pp-typing", children: [
2457
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {}),
2458
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {}),
2459
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {})
1581
2460
  ] }),
1582
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: messagesEndRef })
2461
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref: messagesEndRef })
1583
2462
  ] }),
1584
- messageMenu && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2463
+ messageMenu && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1585
2464
  "div",
1586
2465
  {
1587
2466
  class: "pp-message-menu",
1588
2467
  style: { top: `${messageMenu.y}px`, left: `${messageMenu.x}px` },
1589
2468
  children: [
1590
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { onClick: () => handleReply(messageMenu.message), children: [
1591
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReplyIcon, { color: actionIconColor }),
2469
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { onClick: () => handleReply(messageMenu.message), children: [
2470
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReplyIcon, { color: actionIconColor }),
1592
2471
  " Reply"
1593
2472
  ] }),
1594
- messageMenu.message.sender === "visitor" && !messageMenu.message.deletedAt && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1595
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { onClick: () => handleStartEdit(messageMenu.message), children: [
1596
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EditIcon, { color: actionIconColor }),
2473
+ messageMenu.message.sender === "visitor" && !messageMenu.message.deletedAt && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2474
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { onClick: () => handleStartEdit(messageMenu.message), children: [
2475
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EditIcon, { color: actionIconColor }),
1597
2476
  " Edit"
1598
2477
  ] }),
1599
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { class: "pp-menu-delete", onClick: () => handleDelete(messageMenu.message), children: [
1600
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DeleteIcon, { color: "#ef4444" }),
2478
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { class: "pp-menu-delete", onClick: () => handleDelete(messageMenu.message), children: [
2479
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DeleteIcon, { color: "#ef4444" }),
1601
2480
  " Delete"
1602
2481
  ] })
1603
2482
  ] })
1604
2483
  ]
1605
2484
  }
1606
2485
  ),
1607
- editingMessage && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-edit-modal", children: [
1608
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-edit-header", children: [
1609
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Edit message" }),
1610
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: handleCancelEdit, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CloseIcon, {}) })
2486
+ editingMessage && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-edit-modal", children: [
2487
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-edit-header", children: [
2488
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Edit message" }),
2489
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: handleCancelEdit, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CloseIcon, {}) })
1611
2490
  ] }),
1612
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2491
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1613
2492
  "textarea",
1614
2493
  {
1615
2494
  class: "pp-edit-input",
@@ -1618,41 +2497,41 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1618
2497
  autoFocus: true
1619
2498
  }
1620
2499
  ),
1621
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-edit-actions", children: [
1622
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { class: "pp-edit-cancel", onClick: handleCancelEdit, children: "Cancel" }),
1623
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { class: "pp-edit-save", onClick: handleSaveEdit, disabled: !editContent.trim(), children: "Save" })
2500
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-edit-actions", children: [
2501
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { class: "pp-edit-cancel", onClick: handleCancelEdit, children: "Cancel" }),
2502
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { class: "pp-edit-save", onClick: handleSaveEdit, disabled: !editContent.trim(), children: "Save" })
1624
2503
  ] })
1625
2504
  ] }),
1626
- replyingTo && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-reply-preview", children: [
1627
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-reply-preview-content", children: [
1628
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-reply-label", children: "Replying to" }),
1629
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { class: "pp-reply-text", children: [
1630
- 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} " }),
1631
- replyingTo.content ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
2505
+ replyingTo && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-reply-preview", children: [
2506
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-reply-preview-content", children: [
2507
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-reply-label", children: "Replying to" }),
2508
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { class: "pp-reply-text", children: [
2509
+ 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} " }),
2510
+ replyingTo.content ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
1632
2511
  replyingTo.content.slice(0, 50),
1633
2512
  replyingTo.content.length > 50 ? "..." : ""
1634
2513
  ] }) : replyingTo.attachments?.[0]?.mimeType.startsWith("image/") ? "Photo" : "File"
1635
2514
  ] })
1636
2515
  ] }),
1637
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { class: "pp-reply-cancel", onClick: handleCancelReply, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CloseIcon, {}) })
2516
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { class: "pp-reply-cancel", onClick: handleCancelReply, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CloseIcon, {}) })
1638
2517
  ] }),
1639
- 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: [
1640
- 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 }) }),
1641
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2518
+ 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: [
2519
+ 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 }) }),
2520
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1642
2521
  "button",
1643
2522
  {
1644
2523
  class: "pp-remove-attachment",
1645
2524
  onClick: () => handleRemoveAttachment(pending.id),
1646
2525
  "aria-label": "Remove attachment",
1647
2526
  type: "button",
1648
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CloseIcon, {})
2527
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CloseIcon, {})
1649
2528
  }
1650
2529
  ),
1651
- pending.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-upload-progress", style: { width: `${pending.progress}%` } }),
1652
- pending.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { class: "pp-upload-error", title: pending.error, children: "!" })
2530
+ pending.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-upload-progress", style: { width: `${pending.progress}%` } }),
2531
+ pending.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { class: "pp-upload-error", title: pending.error, children: "!" })
1653
2532
  ] }, pending.id)) }),
1654
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", { class: "pp-input-form", onSubmit: handleSubmit, children: [
1655
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2533
+ !shouldShowPreChat && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { class: "pp-input-form", onSubmit: handleSubmit, children: [
2534
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1656
2535
  "input",
1657
2536
  {
1658
2537
  ref: (el) => {
@@ -1667,7 +2546,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1667
2546
  multiple: true
1668
2547
  }
1669
2548
  ),
1670
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2549
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1671
2550
  "button",
1672
2551
  {
1673
2552
  type: "button",
@@ -1675,10 +2554,10 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1675
2554
  onClick: () => fileInputRef.current?.click(),
1676
2555
  disabled: !isConnected || isUploading,
1677
2556
  "aria-label": "Attach file",
1678
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AttachIcon, {})
2557
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(AttachIcon, {})
1679
2558
  }
1680
2559
  ),
1681
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2560
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1682
2561
  "input",
1683
2562
  {
1684
2563
  ref: inputRef,
@@ -1690,20 +2569,20 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1690
2569
  disabled: !isConnected
1691
2570
  }
1692
2571
  ),
1693
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2572
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1694
2573
  "button",
1695
2574
  {
1696
2575
  type: "submit",
1697
2576
  class: "pp-send-btn",
1698
2577
  disabled: !inputValue.trim() && pendingAttachments.filter((a) => a.status === "ready").length === 0 || !isConnected || isUploading,
1699
2578
  "aria-label": "Send message",
1700
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SendIcon, {})
2579
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SendIcon, {})
1701
2580
  }
1702
2581
  )
1703
2582
  ] }),
1704
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-footer", children: [
2583
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-footer", children: [
1705
2584
  "Powered by ",
1706
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: "https://pocketping.io", target: "_blank", rel: "noopener", children: "PocketPing" })
2585
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { href: "https://pocketping.io", target: "_blank", rel: "noopener", children: "PocketPing" })
1707
2586
  ] })
1708
2587
  ]
1709
2588
  }
@@ -1731,90 +2610,90 @@ function formatTime(timestamp) {
1731
2610
  return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
1732
2611
  }
1733
2612
  function ChatIcon() {
1734
- 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" }) });
2613
+ 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" }) });
1735
2614
  }
1736
2615
  function CloseIcon() {
1737
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1738
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1739
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2616
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2617
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2618
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1740
2619
  ] });
1741
2620
  }
1742
2621
  function SendIcon() {
1743
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1744
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
1745
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
2622
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2623
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
2624
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
1746
2625
  ] });
1747
2626
  }
1748
2627
  function StatusIcon({ status }) {
1749
2628
  if (!status || status === "sending" || status === "sent") {
1750
- 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" }) });
2629
+ 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" }) });
1751
2630
  }
1752
2631
  if (status === "delivered") {
1753
- 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: [
1754
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "1 8 5 12 11 4" }),
1755
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "7 8 11 12 17 4" })
2632
+ 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: [
2633
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "1 8 5 12 11 4" }),
2634
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "7 8 11 12 17 4" })
1756
2635
  ] });
1757
2636
  }
1758
2637
  if (status === "read") {
1759
- 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: [
1760
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "1 8 5 12 11 4" }),
1761
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "7 8 11 12 17 4" })
2638
+ 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: [
2639
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "1 8 5 12 11 4" }),
2640
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "7 8 11 12 17 4" })
1762
2641
  ] });
1763
2642
  }
1764
2643
  return null;
1765
2644
  }
1766
2645
  function AttachIcon() {
1767
- 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" }) });
2646
+ 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" }) });
1768
2647
  }
1769
2648
  function ReplyIcon({ color, size = 16 }) {
1770
2649
  const strokeColor = color || "currentColor";
1771
- 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: [
1772
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "9 17 4 12 9 7" }),
1773
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M20 18v-2a4 4 0 0 0-4-4H4" })
2650
+ 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: [
2651
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "9 17 4 12 9 7" }),
2652
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M20 18v-2a4 4 0 0 0-4-4H4" })
1774
2653
  ] });
1775
2654
  }
1776
2655
  function EditIcon({ color, size = 16 }) {
1777
2656
  const strokeColor = color || "currentColor";
1778
- 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" }) });
2657
+ 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" }) });
1779
2658
  }
1780
2659
  function DeleteIcon({ color, size = 16 }) {
1781
2660
  const strokeColor = color || "currentColor";
1782
- 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: [
1783
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "3 6 5 6 21 6" }),
1784
- /* @__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" })
2661
+ 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: [
2662
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "3 6 5 6 21 6" }),
2663
+ /* @__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" })
1785
2664
  ] });
1786
2665
  }
1787
2666
  function FileIcon({ mimeType }) {
1788
2667
  if (mimeType === "application/pdf") {
1789
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1790
- /* @__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" }),
1791
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "14 2 14 8 20 8" }),
1792
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 15h6" }),
1793
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 11h6" })
2668
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2669
+ /* @__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" }),
2670
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "14 2 14 8 20 8" }),
2671
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 15h6" }),
2672
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 11h6" })
1794
2673
  ] });
1795
2674
  }
1796
2675
  if (mimeType.startsWith("audio/")) {
1797
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1798
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 18V5l12-2v13" }),
1799
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "6", cy: "18", r: "3" }),
1800
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "18", cy: "16", r: "3" })
2676
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2677
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 18V5l12-2v13" }),
2678
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "6", cy: "18", r: "3" }),
2679
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "18", cy: "16", r: "3" })
1801
2680
  ] });
1802
2681
  }
1803
2682
  if (mimeType.startsWith("video/")) {
1804
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1805
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2.18", ry: "2.18" }),
1806
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "7", y1: "2", x2: "7", y2: "22" }),
1807
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "17", y1: "2", x2: "17", y2: "22" }),
1808
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
1809
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "2", y1: "7", x2: "7", y2: "7" }),
1810
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "2", y1: "17", x2: "7", y2: "17" }),
1811
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "17", y1: "17", x2: "22", y2: "17" }),
1812
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "17", y1: "7", x2: "22", y2: "7" })
2683
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2684
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2.18", ry: "2.18" }),
2685
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "7", y1: "2", x2: "7", y2: "22" }),
2686
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "17", y1: "2", x2: "17", y2: "22" }),
2687
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
2688
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "2", y1: "7", x2: "7", y2: "7" }),
2689
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "2", y1: "17", x2: "7", y2: "17" }),
2690
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "17", y1: "17", x2: "22", y2: "17" }),
2691
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("line", { x1: "17", y1: "7", x2: "22", y2: "7" })
1813
2692
  ] });
1814
2693
  }
1815
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1816
- /* @__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" }),
1817
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "14 2 14 8 20 8" })
2694
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2695
+ /* @__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" }),
2696
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "14 2 14 8 20 8" })
1818
2697
  ] });
1819
2698
  }
1820
2699
  function AttachmentDisplay({ attachment }) {
@@ -1827,28 +2706,28 @@ function AttachmentDisplay({ attachment }) {
1827
2706
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
1828
2707
  };
1829
2708
  if (isImage) {
1830
- 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 }) });
2709
+ 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 }) });
1831
2710
  }
1832
2711
  if (isAudio) {
1833
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-attachment pp-attachment-audio", children: [
1834
- /* @__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 }) }),
1835
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-attachment-name", children: attachment.filename })
2712
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-attachment pp-attachment-audio", children: [
2713
+ /* @__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 }) }),
2714
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-attachment-name", children: attachment.filename })
1836
2715
  ] });
1837
2716
  }
1838
2717
  if (isVideo) {
1839
- 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 }) }) });
2718
+ 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 }) }) });
1840
2719
  }
1841
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-file", children: [
1842
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileIcon, { mimeType: attachment.mimeType }),
1843
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "pp-attachment-info", children: [
1844
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-attachment-name", children: attachment.filename }),
1845
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { class: "pp-attachment-size", children: formatSize(attachment.size) })
2720
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-file", children: [
2721
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FileIcon, { mimeType: attachment.mimeType }),
2722
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "pp-attachment-info", children: [
2723
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-attachment-name", children: attachment.filename }),
2724
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { class: "pp-attachment-size", children: formatSize(attachment.size) })
1846
2725
  ] })
1847
2726
  ] });
1848
2727
  }
1849
2728
 
1850
2729
  // src/version.ts
1851
- var VERSION = "0.3.6";
2730
+ var VERSION = "0.3.7";
1852
2731
 
1853
2732
  // src/client.ts
1854
2733
  var PocketPingClient = class {
@@ -1908,7 +2787,8 @@ var PocketPingClient = class {
1908
2787
  visitorId: response.visitorId,
1909
2788
  operatorOnline: response.operatorOnline ?? false,
1910
2789
  messages: response.messages ?? [],
1911
- identity: response.identity || storedIdentity || void 0
2790
+ identity: response.identity || storedIdentity || void 0,
2791
+ preChatForm: response.preChatForm
1912
2792
  };
1913
2793
  if (response.operatorName) {
1914
2794
  this.config.operatorName = response.operatorName;
@@ -2264,6 +3144,36 @@ var PocketPingClient = class {
2264
3144
  }
2265
3145
  }
2266
3146
  }
3147
+ /**
3148
+ * Submit pre-chat form data (email and/or phone)
3149
+ * @param data - Form data containing email and/or phone
3150
+ */
3151
+ async submitPreChat(data) {
3152
+ if (!this.session) {
3153
+ throw new Error("[PocketPing] Not connected");
3154
+ }
3155
+ if (!data.email && !data.phone) {
3156
+ throw new Error("[PocketPing] Either email or phone is required");
3157
+ }
3158
+ try {
3159
+ await this.fetch("/prechat", {
3160
+ method: "POST",
3161
+ body: JSON.stringify({
3162
+ sessionId: this.session.sessionId,
3163
+ email: data.email,
3164
+ phone: data.phone,
3165
+ phoneCountry: data.phoneCountry
3166
+ })
3167
+ });
3168
+ if (this.session.preChatForm) {
3169
+ this.session.preChatForm.completed = true;
3170
+ }
3171
+ this.emit("preChatCompleted", data);
3172
+ } catch (err) {
3173
+ console.error("[PocketPing] Failed to submit pre-chat form:", err);
3174
+ throw err;
3175
+ }
3176
+ }
2267
3177
  /**
2268
3178
  * Reset the user identity and optionally start a new session
2269
3179
  * Call on user logout to clear user data
@@ -2913,6 +3823,12 @@ var PocketPingClient = class {
2913
3823
  this.session.messages.push(message);
2914
3824
  this.emit("message", message);
2915
3825
  this.config.onMessage?.(message);
3826
+ if (message.sender !== "visitor" && !this.isOpen) {
3827
+ const autoOpen = this.config.autoOpenOnMessage ?? true;
3828
+ if (autoOpen) {
3829
+ this.setOpen(true);
3830
+ }
3831
+ }
2916
3832
  }
2917
3833
  }
2918
3834
  if (message.sender !== "visitor") {
@@ -3071,6 +3987,12 @@ var PocketPingClient = class {
3071
3987
  this.session.messages.push(message);
3072
3988
  this.emit("message", message);
3073
3989
  this.config.onMessage?.(message);
3990
+ if (message.sender !== "visitor" && !this.isOpen) {
3991
+ const autoOpen = this.config.autoOpenOnMessage ?? true;
3992
+ if (autoOpen) {
3993
+ this.setOpen(true);
3994
+ }
3995
+ }
3074
3996
  }
3075
3997
  }
3076
3998
  } catch (err) {