@pocketping/widget 1.6.0 → 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.js CHANGED
@@ -2,8 +2,8 @@
2
2
  import { render, h as h2 } from "preact";
3
3
 
4
4
  // src/components/ChatWidget.tsx
5
- import { Fragment } from "preact";
6
- import { useState, useEffect, useRef, useCallback } from "preact/hooks";
5
+ import { Fragment as Fragment2 } from "preact";
6
+ import { useState as useState2, useEffect as useEffect2, useRef as useRef2, useCallback } from "preact/hooks";
7
7
 
8
8
  // src/components/styles.ts
9
9
  function styles(primaryColor, theme) {
@@ -24,6 +24,17 @@ function styles(primaryColor, theme) {
24
24
  color: ${colors.text};
25
25
  }
26
26
 
27
+ #pocketping-container,
28
+ #pocketping-container * {
29
+ box-sizing: border-box;
30
+ }
31
+
32
+ #pocketping-container img,
33
+ #pocketping-container video {
34
+ max-width: 100%;
35
+ height: auto;
36
+ }
37
+
27
38
  .pp-toggle {
28
39
  position: fixed;
29
40
  width: 56px;
@@ -219,10 +230,14 @@ function styles(primaryColor, theme) {
219
230
  .pp-messages {
220
231
  flex: 1;
221
232
  overflow-y: auto;
222
- padding: 12px;
233
+ padding: 32px 12px 12px 12px;
223
234
  display: flex;
224
235
  flex-direction: column;
225
236
  gap: 3px;
237
+ overscroll-behavior: contain;
238
+ -webkit-overflow-scrolling: touch;
239
+ /* Ensure proper stacking context for positioned elements */
240
+ position: relative;
226
241
  }
227
242
 
228
243
  .pp-welcome {
@@ -248,6 +263,75 @@ function styles(primaryColor, theme) {
248
263
  font-weight: 500;
249
264
  }
250
265
 
266
+ /* Swipe container for mobile actions */
267
+ .pp-message-swipe-container {
268
+ position: relative;
269
+ display: flex;
270
+ align-items: stretch;
271
+ overflow: visible;
272
+ touch-action: pan-y;
273
+ }
274
+
275
+ .pp-swipe-left {
276
+ justify-content: flex-end;
277
+ }
278
+
279
+ .pp-swipe-right {
280
+ justify-content: flex-start;
281
+ }
282
+
283
+ .pp-swipe-actions {
284
+ position: absolute;
285
+ right: 0;
286
+ top: 0;
287
+ bottom: 0;
288
+ display: flex;
289
+ align-items: center;
290
+ gap: 4px;
291
+ padding-right: 8px;
292
+ }
293
+
294
+ .pp-swipe-left .pp-swipe-actions {
295
+ right: 0;
296
+ left: auto;
297
+ }
298
+
299
+ .pp-swipe-right .pp-swipe-actions {
300
+ left: 0;
301
+ right: auto;
302
+ padding-left: 8px;
303
+ padding-right: 0;
304
+ }
305
+
306
+ .pp-swipe-action {
307
+ width: 32px;
308
+ height: 32px;
309
+ border: none;
310
+ border-radius: 50%;
311
+ cursor: pointer;
312
+ display: flex;
313
+ align-items: center;
314
+ justify-content: center;
315
+ opacity: 0.9;
316
+ }
317
+
318
+ .pp-swipe-action svg {
319
+ width: 16px;
320
+ height: 16px;
321
+ }
322
+
323
+ .pp-swipe-reply {
324
+ background: ${primaryColor};
325
+ }
326
+
327
+ .pp-swipe-edit {
328
+ background: #3b82f6;
329
+ }
330
+
331
+ .pp-swipe-delete {
332
+ background: #ef4444;
333
+ }
334
+
251
335
  .pp-message {
252
336
  max-width: 85%;
253
337
  padding: 6px 10px;
@@ -258,12 +342,15 @@ function styles(primaryColor, theme) {
258
342
  -webkit-user-select: text;
259
343
  font-size: 14px;
260
344
  line-height: 1.35;
345
+ display: flex;
346
+ flex-direction: column;
347
+ will-change: transform;
261
348
  }
262
349
 
263
350
  /* Hover actions container - positioned above message (Slack style) */
264
351
  .pp-message-actions {
265
352
  position: absolute;
266
- top: -28px;
353
+ top: -32px;
267
354
  display: flex;
268
355
  gap: 2px;
269
356
  background: ${colors.bg};
@@ -276,6 +363,8 @@ function styles(primaryColor, theme) {
276
363
  z-index: 10;
277
364
  /* Reset color inheritance from message */
278
365
  color: ${colors.textSecondary};
366
+ /* Ensure actions don't interfere with layout */
367
+ pointer-events: auto;
279
368
  }
280
369
 
281
370
  @keyframes pp-actions-fade-in {
@@ -371,18 +460,19 @@ function styles(primaryColor, theme) {
371
460
  }
372
461
 
373
462
  .pp-message-content {
374
- display: inline;
463
+ display: block;
464
+ flex: 1;
375
465
  }
376
466
 
377
467
  .pp-message-time {
378
468
  font-size: 10px;
379
469
  opacity: 0.6;
380
- display: inline-flex;
470
+ display: flex;
381
471
  align-items: center;
382
472
  gap: 3px;
383
- float: right;
384
- margin-left: 8px;
385
- margin-top: 4px;
473
+ justify-content: flex-end;
474
+ margin-top: 8px;
475
+ flex-shrink: 0;
386
476
  }
387
477
 
388
478
  .pp-ai-badge {
@@ -674,7 +764,10 @@ function styles(primaryColor, theme) {
674
764
  display: flex;
675
765
  flex-direction: column;
676
766
  gap: 8px;
677
- margin-top: 4px;
767
+ margin-top: 6px;
768
+ max-width: 100%;
769
+ align-items: flex-start;
770
+ flex-shrink: 0;
678
771
  }
679
772
 
680
773
  .pp-attachment {
@@ -685,11 +778,22 @@ function styles(primaryColor, theme) {
685
778
  overflow: hidden;
686
779
  }
687
780
 
781
+ .pp-attachment-image,
782
+ .pp-attachment-video,
783
+ .pp-attachment-audio {
784
+ width: 240px;
785
+ max-width: 100%;
786
+ }
787
+
688
788
  .pp-attachment-image img {
689
- max-width: 200px;
789
+ width: 100% !important;
790
+ height: auto !important;
791
+ max-width: 240px;
690
792
  max-height: 200px;
691
793
  border-radius: 8px;
692
794
  display: block;
795
+ object-fit: cover !important;
796
+ object-position: center;
693
797
  }
694
798
 
695
799
  .pp-attachment-audio {
@@ -699,7 +803,8 @@ function styles(primaryColor, theme) {
699
803
  }
700
804
 
701
805
  .pp-attachment-audio audio {
702
- width: 200px;
806
+ width: 240px;
807
+ max-width: 100%;
703
808
  height: 36px;
704
809
  }
705
810
 
@@ -709,14 +814,18 @@ function styles(primaryColor, theme) {
709
814
  white-space: nowrap;
710
815
  overflow: hidden;
711
816
  text-overflow: ellipsis;
712
- max-width: 200px;
817
+ max-width: 100%;
713
818
  }
714
819
 
715
820
  .pp-attachment-video video {
716
- max-width: 200px;
717
- max-height: 200px;
821
+ width: 100% !important;
822
+ height: auto !important;
823
+ max-width: 240px;
824
+ max-height: none;
718
825
  border-radius: 8px;
719
826
  display: block;
827
+ object-fit: contain !important;
828
+ object-position: center;
720
829
  }
721
830
 
722
831
  .pp-attachment-file {
@@ -1067,11 +1176,619 @@ function styles(primaryColor, theme) {
1067
1176
  margin-left: 4px;
1068
1177
  font-style: italic;
1069
1178
  }
1179
+
1180
+ /* Pre-Chat Form */
1181
+ .pp-prechat {
1182
+ flex: 1;
1183
+ display: flex;
1184
+ flex-direction: column;
1185
+ padding: 24px 20px;
1186
+ overflow-y: auto;
1187
+ }
1188
+
1189
+ .pp-prechat-title {
1190
+ font-size: 18px;
1191
+ font-weight: 600;
1192
+ margin-bottom: 8px;
1193
+ color: ${colors.text};
1194
+ }
1195
+
1196
+ .pp-prechat-subtitle {
1197
+ font-size: 13px;
1198
+ color: ${colors.textSecondary};
1199
+ margin-bottom: 24px;
1200
+ }
1201
+
1202
+ .pp-prechat-tabs {
1203
+ display: flex;
1204
+ gap: 8px;
1205
+ margin-bottom: 20px;
1206
+ }
1207
+
1208
+ .pp-prechat-tab {
1209
+ flex: 1;
1210
+ padding: 10px;
1211
+ border: 1px solid ${colors.border};
1212
+ border-radius: 8px;
1213
+ background: transparent;
1214
+ color: ${colors.textSecondary};
1215
+ font-size: 13px;
1216
+ cursor: pointer;
1217
+ transition: all 0.2s;
1218
+ display: flex;
1219
+ align-items: center;
1220
+ justify-content: center;
1221
+ gap: 6px;
1222
+ }
1223
+
1224
+ .pp-prechat-tab:hover {
1225
+ background: ${colors.bgSecondary};
1226
+ }
1227
+
1228
+ .pp-prechat-tab.active {
1229
+ background: ${primaryColor}15;
1230
+ border-color: ${primaryColor};
1231
+ color: ${primaryColor};
1232
+ }
1233
+
1234
+ .pp-prechat-tab svg {
1235
+ width: 16px;
1236
+ height: 16px;
1237
+ }
1238
+
1239
+ .pp-prechat-field {
1240
+ margin-bottom: 16px;
1241
+ }
1242
+
1243
+ .pp-prechat-label {
1244
+ display: block;
1245
+ font-size: 12px;
1246
+ font-weight: 500;
1247
+ color: ${colors.textSecondary};
1248
+ margin-bottom: 6px;
1249
+ }
1250
+
1251
+ .pp-prechat-input {
1252
+ width: 100%;
1253
+ height: 44px;
1254
+ padding: 0 14px;
1255
+ border: 1px solid ${colors.border};
1256
+ border-radius: 8px;
1257
+ background: ${colors.bg};
1258
+ color: ${colors.text};
1259
+ font-size: 14px;
1260
+ outline: none;
1261
+ transition: border-color 0.2s;
1262
+ box-sizing: border-box;
1263
+ }
1264
+
1265
+ .pp-prechat-input:focus {
1266
+ border-color: ${primaryColor};
1267
+ }
1268
+
1269
+ .pp-prechat-input::placeholder {
1270
+ color: ${colors.textSecondary};
1271
+ }
1272
+
1273
+ .pp-prechat-input.error {
1274
+ border-color: #ef4444;
1275
+ }
1276
+
1277
+ .pp-prechat-error {
1278
+ color: #ef4444;
1279
+ font-size: 12px;
1280
+ margin-top: 4px;
1281
+ }
1282
+
1283
+ .pp-phone-input-wrapper {
1284
+ display: flex;
1285
+ gap: 8px;
1286
+ }
1287
+
1288
+ .pp-country-select {
1289
+ position: relative;
1290
+ }
1291
+
1292
+ .pp-country-btn {
1293
+ display: flex;
1294
+ align-items: center;
1295
+ gap: 6px;
1296
+ height: 44px;
1297
+ padding: 0 10px;
1298
+ border: 1px solid ${colors.border};
1299
+ border-radius: 8px;
1300
+ background: ${colors.bg};
1301
+ color: ${colors.text};
1302
+ font-size: 14px;
1303
+ cursor: pointer;
1304
+ transition: border-color 0.2s;
1305
+ }
1306
+
1307
+ .pp-country-btn:focus {
1308
+ border-color: ${primaryColor};
1309
+ outline: none;
1310
+ }
1311
+
1312
+ .pp-country-flag {
1313
+ font-size: 18px;
1314
+ line-height: 1;
1315
+ }
1316
+
1317
+ .pp-country-code {
1318
+ font-size: 13px;
1319
+ color: ${colors.textSecondary};
1320
+ }
1321
+
1322
+ .pp-country-chevron {
1323
+ width: 12px;
1324
+ height: 12px;
1325
+ color: ${colors.textSecondary};
1326
+ }
1327
+
1328
+ .pp-country-dropdown {
1329
+ position: absolute;
1330
+ top: calc(100% + 4px);
1331
+ left: 0;
1332
+ width: 280px;
1333
+ max-height: 280px;
1334
+ overflow-y: auto;
1335
+ background: ${colors.bg};
1336
+ border: 1px solid ${colors.border};
1337
+ border-radius: 8px;
1338
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
1339
+ z-index: 100;
1340
+ }
1341
+
1342
+ .pp-country-search {
1343
+ position: sticky;
1344
+ top: 0;
1345
+ padding: 8px;
1346
+ background: ${colors.bg};
1347
+ border-bottom: 1px solid ${colors.border};
1348
+ }
1349
+
1350
+ .pp-country-search-input {
1351
+ width: 100%;
1352
+ height: 36px;
1353
+ padding: 0 12px;
1354
+ border: 1px solid ${colors.border};
1355
+ border-radius: 6px;
1356
+ background: ${colors.bgSecondary};
1357
+ color: ${colors.text};
1358
+ font-size: 13px;
1359
+ outline: none;
1360
+ box-sizing: border-box;
1361
+ }
1362
+
1363
+ .pp-country-search-input:focus {
1364
+ border-color: ${primaryColor};
1365
+ }
1366
+
1367
+ .pp-country-list {
1368
+ padding: 4px;
1369
+ }
1370
+
1371
+ .pp-country-option {
1372
+ display: flex;
1373
+ align-items: center;
1374
+ gap: 10px;
1375
+ padding: 10px 12px;
1376
+ cursor: pointer;
1377
+ border-radius: 6px;
1378
+ transition: background 0.15s;
1379
+ }
1380
+
1381
+ .pp-country-option:hover {
1382
+ background: ${colors.bgSecondary};
1383
+ }
1384
+
1385
+ .pp-country-option.selected {
1386
+ background: ${primaryColor}15;
1387
+ }
1388
+
1389
+ .pp-country-name {
1390
+ flex: 1;
1391
+ font-size: 13px;
1392
+ color: ${colors.text};
1393
+ }
1394
+
1395
+ .pp-country-dial {
1396
+ font-size: 12px;
1397
+ color: ${colors.textSecondary};
1398
+ }
1399
+
1400
+ .pp-phone-number-input {
1401
+ flex: 1;
1402
+ }
1403
+
1404
+ .pp-prechat-submit {
1405
+ width: 100%;
1406
+ height: 44px;
1407
+ margin-top: 8px;
1408
+ border: none;
1409
+ border-radius: 8px;
1410
+ background: ${primaryColor};
1411
+ color: white;
1412
+ font-size: 14px;
1413
+ font-weight: 500;
1414
+ cursor: pointer;
1415
+ transition: opacity 0.2s, transform 0.1s;
1416
+ }
1417
+
1418
+ .pp-prechat-submit:hover:not(:disabled) {
1419
+ opacity: 0.9;
1420
+ }
1421
+
1422
+ .pp-prechat-submit:active:not(:disabled) {
1423
+ transform: scale(0.98);
1424
+ }
1425
+
1426
+ .pp-prechat-submit:disabled {
1427
+ opacity: 0.5;
1428
+ cursor: not-allowed;
1429
+ }
1430
+
1431
+ .pp-prechat-skip {
1432
+ width: 100%;
1433
+ padding: 12px;
1434
+ margin-top: 8px;
1435
+ border: none;
1436
+ background: transparent;
1437
+ color: ${colors.textSecondary};
1438
+ font-size: 13px;
1439
+ cursor: pointer;
1440
+ transition: color 0.2s;
1441
+ }
1442
+
1443
+ .pp-prechat-skip:hover {
1444
+ color: ${colors.text};
1445
+ }
1070
1446
  `;
1071
1447
  }
1072
1448
 
1449
+ // src/components/PreChatForm.tsx
1450
+ import { useState, useRef, useEffect } from "preact/hooks";
1451
+ import { parsePhoneNumber, isValidPhoneNumber } from "libphonenumber-js/min";
1452
+
1453
+ // src/data/countries.ts
1454
+ var countries = [
1455
+ // Europe
1456
+ { code: "FR", name: "France", dialCode: "+33", flag: "\u{1F1EB}\u{1F1F7}" },
1457
+ { code: "DE", name: "Germany", dialCode: "+49", flag: "\u{1F1E9}\u{1F1EA}" },
1458
+ { code: "GB", name: "United Kingdom", dialCode: "+44", flag: "\u{1F1EC}\u{1F1E7}" },
1459
+ { code: "ES", name: "Spain", dialCode: "+34", flag: "\u{1F1EA}\u{1F1F8}" },
1460
+ { code: "IT", name: "Italy", dialCode: "+39", flag: "\u{1F1EE}\u{1F1F9}" },
1461
+ { code: "PT", name: "Portugal", dialCode: "+351", flag: "\u{1F1F5}\u{1F1F9}" },
1462
+ { code: "NL", name: "Netherlands", dialCode: "+31", flag: "\u{1F1F3}\u{1F1F1}" },
1463
+ { code: "BE", name: "Belgium", dialCode: "+32", flag: "\u{1F1E7}\u{1F1EA}" },
1464
+ { code: "CH", name: "Switzerland", dialCode: "+41", flag: "\u{1F1E8}\u{1F1ED}" },
1465
+ { code: "AT", name: "Austria", dialCode: "+43", flag: "\u{1F1E6}\u{1F1F9}" },
1466
+ { code: "SE", name: "Sweden", dialCode: "+46", flag: "\u{1F1F8}\u{1F1EA}" },
1467
+ { code: "NO", name: "Norway", dialCode: "+47", flag: "\u{1F1F3}\u{1F1F4}" },
1468
+ { code: "DK", name: "Denmark", dialCode: "+45", flag: "\u{1F1E9}\u{1F1F0}" },
1469
+ { code: "FI", name: "Finland", dialCode: "+358", flag: "\u{1F1EB}\u{1F1EE}" },
1470
+ { code: "PL", name: "Poland", dialCode: "+48", flag: "\u{1F1F5}\u{1F1F1}" },
1471
+ { code: "CZ", name: "Czech Republic", dialCode: "+420", flag: "\u{1F1E8}\u{1F1FF}" },
1472
+ { code: "GR", name: "Greece", dialCode: "+30", flag: "\u{1F1EC}\u{1F1F7}" },
1473
+ { code: "IE", name: "Ireland", dialCode: "+353", flag: "\u{1F1EE}\u{1F1EA}" },
1474
+ { code: "RO", name: "Romania", dialCode: "+40", flag: "\u{1F1F7}\u{1F1F4}" },
1475
+ { code: "HU", name: "Hungary", dialCode: "+36", flag: "\u{1F1ED}\u{1F1FA}" },
1476
+ // North America
1477
+ { code: "US", name: "United States", dialCode: "+1", flag: "\u{1F1FA}\u{1F1F8}" },
1478
+ { code: "CA", name: "Canada", dialCode: "+1", flag: "\u{1F1E8}\u{1F1E6}" },
1479
+ { code: "MX", name: "Mexico", dialCode: "+52", flag: "\u{1F1F2}\u{1F1FD}" },
1480
+ // South America
1481
+ { code: "BR", name: "Brazil", dialCode: "+55", flag: "\u{1F1E7}\u{1F1F7}" },
1482
+ { code: "AR", name: "Argentina", dialCode: "+54", flag: "\u{1F1E6}\u{1F1F7}" },
1483
+ { code: "CL", name: "Chile", dialCode: "+56", flag: "\u{1F1E8}\u{1F1F1}" },
1484
+ { code: "CO", name: "Colombia", dialCode: "+57", flag: "\u{1F1E8}\u{1F1F4}" },
1485
+ { code: "PE", name: "Peru", dialCode: "+51", flag: "\u{1F1F5}\u{1F1EA}" },
1486
+ // Asia
1487
+ { code: "CN", name: "China", dialCode: "+86", flag: "\u{1F1E8}\u{1F1F3}" },
1488
+ { code: "JP", name: "Japan", dialCode: "+81", flag: "\u{1F1EF}\u{1F1F5}" },
1489
+ { code: "KR", name: "South Korea", dialCode: "+82", flag: "\u{1F1F0}\u{1F1F7}" },
1490
+ { code: "IN", name: "India", dialCode: "+91", flag: "\u{1F1EE}\u{1F1F3}" },
1491
+ { code: "ID", name: "Indonesia", dialCode: "+62", flag: "\u{1F1EE}\u{1F1E9}" },
1492
+ { code: "TH", name: "Thailand", dialCode: "+66", flag: "\u{1F1F9}\u{1F1ED}" },
1493
+ { code: "VN", name: "Vietnam", dialCode: "+84", flag: "\u{1F1FB}\u{1F1F3}" },
1494
+ { code: "MY", name: "Malaysia", dialCode: "+60", flag: "\u{1F1F2}\u{1F1FE}" },
1495
+ { code: "SG", name: "Singapore", dialCode: "+65", flag: "\u{1F1F8}\u{1F1EC}" },
1496
+ { code: "PH", name: "Philippines", dialCode: "+63", flag: "\u{1F1F5}\u{1F1ED}" },
1497
+ { code: "PK", name: "Pakistan", dialCode: "+92", flag: "\u{1F1F5}\u{1F1F0}" },
1498
+ { code: "BD", name: "Bangladesh", dialCode: "+880", flag: "\u{1F1E7}\u{1F1E9}" },
1499
+ // Middle East
1500
+ { code: "AE", name: "United Arab Emirates", dialCode: "+971", flag: "\u{1F1E6}\u{1F1EA}" },
1501
+ { code: "SA", name: "Saudi Arabia", dialCode: "+966", flag: "\u{1F1F8}\u{1F1E6}" },
1502
+ { code: "IL", name: "Israel", dialCode: "+972", flag: "\u{1F1EE}\u{1F1F1}" },
1503
+ { code: "TR", name: "Turkey", dialCode: "+90", flag: "\u{1F1F9}\u{1F1F7}" },
1504
+ { code: "EG", name: "Egypt", dialCode: "+20", flag: "\u{1F1EA}\u{1F1EC}" },
1505
+ // Africa
1506
+ { code: "ZA", name: "South Africa", dialCode: "+27", flag: "\u{1F1FF}\u{1F1E6}" },
1507
+ { code: "NG", name: "Nigeria", dialCode: "+234", flag: "\u{1F1F3}\u{1F1EC}" },
1508
+ { code: "KE", name: "Kenya", dialCode: "+254", flag: "\u{1F1F0}\u{1F1EA}" },
1509
+ { code: "MA", name: "Morocco", dialCode: "+212", flag: "\u{1F1F2}\u{1F1E6}" },
1510
+ { code: "TN", name: "Tunisia", dialCode: "+216", flag: "\u{1F1F9}\u{1F1F3}" },
1511
+ { code: "DZ", name: "Algeria", dialCode: "+213", flag: "\u{1F1E9}\u{1F1FF}" },
1512
+ // Oceania
1513
+ { code: "AU", name: "Australia", dialCode: "+61", flag: "\u{1F1E6}\u{1F1FA}" },
1514
+ { code: "NZ", name: "New Zealand", dialCode: "+64", flag: "\u{1F1F3}\u{1F1FF}" },
1515
+ // Russia & CIS
1516
+ { code: "RU", name: "Russia", dialCode: "+7", flag: "\u{1F1F7}\u{1F1FA}" },
1517
+ { code: "UA", name: "Ukraine", dialCode: "+380", flag: "\u{1F1FA}\u{1F1E6}" }
1518
+ ].sort((a, b) => a.name.localeCompare(b.name));
1519
+ function findCountryByCode(code) {
1520
+ return countries.find((c) => c.code === code.toUpperCase());
1521
+ }
1522
+ var defaultCountry = findCountryByCode("FR");
1523
+
1524
+ // src/components/PreChatForm.tsx
1525
+ import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
1526
+ var EmailIcon = () => /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1527
+ /* @__PURE__ */ jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2" }),
1528
+ /* @__PURE__ */ jsx("path", { d: "M22 7l-10 7L2 7" })
1529
+ ] });
1530
+ var PhoneIcon = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-6-6 19.79 19.79 0 01-3.07-8.67A2 2 0 014.11 2h3a2 2 0 012 1.72 12.84 12.84 0 00.7 2.81 2 2 0 01-.45 2.11L8.09 9.91a16 16 0 006 6l1.27-1.27a2 2 0 012.11-.45 12.84 12.84 0 002.81.7A2 2 0 0122 16.92z" }) });
1531
+ var ChevronIcon = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "M6 9l6 6 6-6" }) });
1532
+ function isValidEmail(email) {
1533
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
1534
+ }
1535
+ function PreChatForm({ client: client2, config, onComplete, onSkip }) {
1536
+ const showEmailOnly = config.fields === "email-only";
1537
+ const showPhoneOnly = config.fields === "phone-only";
1538
+ const showBoth = config.fields === "email-and-phone";
1539
+ const showChoice = config.fields === "email-or-phone";
1540
+ const getDefaultTab = () => {
1541
+ if (showPhoneOnly) return "phone";
1542
+ return "email";
1543
+ };
1544
+ const [activeTab, setActiveTab] = useState(getDefaultTab());
1545
+ const [email, setEmail] = useState("");
1546
+ const [phone, setPhone] = useState("");
1547
+ const [selectedCountry, setSelectedCountry] = useState(defaultCountry);
1548
+ const [isCountryDropdownOpen, setIsCountryDropdownOpen] = useState(false);
1549
+ const [countrySearch, setCountrySearch] = useState("");
1550
+ const [emailError, setEmailError] = useState("");
1551
+ const [phoneError, setPhoneError] = useState("");
1552
+ const [isSubmitting, setIsSubmitting] = useState(false);
1553
+ const countryDropdownRef = useRef(null);
1554
+ const searchInputRef = useRef(null);
1555
+ useEffect(() => {
1556
+ const handleClickOutside = (e) => {
1557
+ if (countryDropdownRef.current && !countryDropdownRef.current.contains(e.target)) {
1558
+ setIsCountryDropdownOpen(false);
1559
+ }
1560
+ };
1561
+ document.addEventListener("mousedown", handleClickOutside);
1562
+ return () => document.removeEventListener("mousedown", handleClickOutside);
1563
+ }, []);
1564
+ useEffect(() => {
1565
+ if (isCountryDropdownOpen && searchInputRef.current) {
1566
+ searchInputRef.current.focus();
1567
+ }
1568
+ }, [isCountryDropdownOpen]);
1569
+ const filteredCountries = countries.filter(
1570
+ (c) => c.name.toLowerCase().includes(countrySearch.toLowerCase()) || c.dialCode.includes(countrySearch) || c.code.toLowerCase().includes(countrySearch.toLowerCase())
1571
+ );
1572
+ const handleCountrySelect = (country) => {
1573
+ setSelectedCountry(country);
1574
+ setIsCountryDropdownOpen(false);
1575
+ setCountrySearch("");
1576
+ };
1577
+ const formatPhoneForDisplay = (value) => {
1578
+ const digits = value.replace(/\D/g, "");
1579
+ return digits;
1580
+ };
1581
+ const handlePhoneChange = (e) => {
1582
+ const target = e.target;
1583
+ const formatted = formatPhoneForDisplay(target.value);
1584
+ setPhone(formatted);
1585
+ setPhoneError("");
1586
+ };
1587
+ const getFullPhoneNumber = () => {
1588
+ if (!phone) return "";
1589
+ return `${selectedCountry.dialCode}${phone}`;
1590
+ };
1591
+ const validateForm = () => {
1592
+ let valid = true;
1593
+ if (showEmailOnly || showBoth) {
1594
+ if (!email.trim()) {
1595
+ setEmailError("Email is required");
1596
+ valid = false;
1597
+ } else if (!isValidEmail(email)) {
1598
+ setEmailError("Please enter a valid email");
1599
+ valid = false;
1600
+ }
1601
+ }
1602
+ if (showPhoneOnly || showBoth) {
1603
+ const fullPhone = getFullPhoneNumber();
1604
+ if (!phone.trim()) {
1605
+ setPhoneError("Phone number is required");
1606
+ valid = false;
1607
+ } else if (!isValidPhoneNumber(fullPhone, selectedCountry.code)) {
1608
+ setPhoneError("Please enter a valid phone number");
1609
+ valid = false;
1610
+ }
1611
+ }
1612
+ if (showChoice) {
1613
+ if (activeTab === "email") {
1614
+ if (!email.trim()) {
1615
+ setEmailError("Email is required");
1616
+ valid = false;
1617
+ } else if (!isValidEmail(email)) {
1618
+ setEmailError("Please enter a valid email");
1619
+ valid = false;
1620
+ }
1621
+ } else {
1622
+ const fullPhone = getFullPhoneNumber();
1623
+ if (!phone.trim()) {
1624
+ setPhoneError("Phone number is required");
1625
+ valid = false;
1626
+ } else if (!isValidPhoneNumber(fullPhone, selectedCountry.code)) {
1627
+ setPhoneError("Please enter a valid phone number");
1628
+ valid = false;
1629
+ }
1630
+ }
1631
+ }
1632
+ return valid;
1633
+ };
1634
+ const handleSubmit = async (e) => {
1635
+ e.preventDefault();
1636
+ if (!validateForm()) return;
1637
+ setIsSubmitting(true);
1638
+ try {
1639
+ const data = {};
1640
+ if (showEmailOnly || showBoth || showChoice && activeTab === "email") {
1641
+ data.email = email.trim();
1642
+ }
1643
+ if (showPhoneOnly || showBoth || showChoice && activeTab === "phone") {
1644
+ const fullPhone = getFullPhoneNumber();
1645
+ const parsed = parsePhoneNumber(fullPhone, selectedCountry.code);
1646
+ if (parsed) {
1647
+ data.phone = parsed.format("E.164");
1648
+ data.phoneCountry = selectedCountry.code;
1649
+ }
1650
+ }
1651
+ await client2.submitPreChat(data);
1652
+ onComplete();
1653
+ } catch (err) {
1654
+ console.error("[PreChatForm] Submit error:", err);
1655
+ if (activeTab === "email" || showEmailOnly || showBoth) {
1656
+ setEmailError("Something went wrong. Please try again.");
1657
+ } else {
1658
+ setPhoneError("Something went wrong. Please try again.");
1659
+ }
1660
+ } finally {
1661
+ setIsSubmitting(false);
1662
+ }
1663
+ };
1664
+ const renderEmailField = () => /* @__PURE__ */ jsxs("div", { class: "pp-prechat-field", children: [
1665
+ /* @__PURE__ */ jsx("label", { class: "pp-prechat-label", children: "Email address" }),
1666
+ /* @__PURE__ */ jsx(
1667
+ "input",
1668
+ {
1669
+ type: "email",
1670
+ class: `pp-prechat-input ${emailError ? "error" : ""}`,
1671
+ placeholder: "you@example.com",
1672
+ value: email,
1673
+ onInput: (e) => {
1674
+ setEmail(e.target.value);
1675
+ setEmailError("");
1676
+ }
1677
+ }
1678
+ ),
1679
+ emailError && /* @__PURE__ */ jsx("div", { class: "pp-prechat-error", children: emailError })
1680
+ ] });
1681
+ const renderPhoneField = () => /* @__PURE__ */ jsxs("div", { class: "pp-prechat-field", children: [
1682
+ /* @__PURE__ */ jsx("label", { class: "pp-prechat-label", children: "Phone number" }),
1683
+ /* @__PURE__ */ jsxs("div", { class: "pp-phone-input-wrapper", children: [
1684
+ /* @__PURE__ */ jsxs("div", { class: "pp-country-select", ref: countryDropdownRef, children: [
1685
+ /* @__PURE__ */ jsxs(
1686
+ "button",
1687
+ {
1688
+ type: "button",
1689
+ class: "pp-country-btn",
1690
+ onClick: () => setIsCountryDropdownOpen(!isCountryDropdownOpen),
1691
+ children: [
1692
+ /* @__PURE__ */ jsx("span", { class: "pp-country-flag", children: selectedCountry.flag }),
1693
+ /* @__PURE__ */ jsx("span", { class: "pp-country-code", children: selectedCountry.dialCode }),
1694
+ /* @__PURE__ */ jsx(ChevronIcon, {})
1695
+ ]
1696
+ }
1697
+ ),
1698
+ isCountryDropdownOpen && /* @__PURE__ */ jsxs("div", { class: "pp-country-dropdown", children: [
1699
+ /* @__PURE__ */ jsx("div", { class: "pp-country-search", children: /* @__PURE__ */ jsx(
1700
+ "input",
1701
+ {
1702
+ ref: searchInputRef,
1703
+ type: "text",
1704
+ class: "pp-country-search-input",
1705
+ placeholder: "Search country...",
1706
+ value: countrySearch,
1707
+ onInput: (e) => setCountrySearch(e.target.value)
1708
+ }
1709
+ ) }),
1710
+ /* @__PURE__ */ jsx("div", { class: "pp-country-list", children: filteredCountries.map((country) => /* @__PURE__ */ jsxs(
1711
+ "div",
1712
+ {
1713
+ class: `pp-country-option ${country.code === selectedCountry.code ? "selected" : ""}`,
1714
+ onClick: () => handleCountrySelect(country),
1715
+ children: [
1716
+ /* @__PURE__ */ jsx("span", { class: "pp-country-flag", children: country.flag }),
1717
+ /* @__PURE__ */ jsx("span", { class: "pp-country-name", children: country.name }),
1718
+ /* @__PURE__ */ jsx("span", { class: "pp-country-dial", children: country.dialCode })
1719
+ ]
1720
+ },
1721
+ country.code
1722
+ )) })
1723
+ ] })
1724
+ ] }),
1725
+ /* @__PURE__ */ jsx(
1726
+ "input",
1727
+ {
1728
+ type: "tel",
1729
+ class: `pp-prechat-input pp-phone-number-input ${phoneError ? "error" : ""}`,
1730
+ placeholder: "612 345 678",
1731
+ value: phone,
1732
+ onInput: handlePhoneChange
1733
+ }
1734
+ )
1735
+ ] }),
1736
+ phoneError && /* @__PURE__ */ jsx("div", { class: "pp-prechat-error", children: phoneError })
1737
+ ] });
1738
+ return /* @__PURE__ */ jsxs("div", { class: "pp-prechat", children: [
1739
+ /* @__PURE__ */ jsx("h2", { class: "pp-prechat-title", children: "How can we reach you?" }),
1740
+ /* @__PURE__ */ jsx("p", { class: "pp-prechat-subtitle", children: showBoth ? "Please provide your contact information so we can follow up if needed." : showChoice ? "Choose how you would like us to contact you." : showEmailOnly ? "Enter your email so we can follow up with you." : "Enter your phone number so we can call you back." }),
1741
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
1742
+ showChoice && /* @__PURE__ */ jsxs("div", { class: "pp-prechat-tabs", children: [
1743
+ /* @__PURE__ */ jsxs(
1744
+ "button",
1745
+ {
1746
+ type: "button",
1747
+ class: `pp-prechat-tab ${activeTab === "email" ? "active" : ""}`,
1748
+ onClick: () => {
1749
+ setActiveTab("email");
1750
+ setPhoneError("");
1751
+ },
1752
+ children: [
1753
+ /* @__PURE__ */ jsx(EmailIcon, {}),
1754
+ "Email"
1755
+ ]
1756
+ }
1757
+ ),
1758
+ /* @__PURE__ */ jsxs(
1759
+ "button",
1760
+ {
1761
+ type: "button",
1762
+ class: `pp-prechat-tab ${activeTab === "phone" ? "active" : ""}`,
1763
+ onClick: () => {
1764
+ setActiveTab("phone");
1765
+ setEmailError("");
1766
+ },
1767
+ children: [
1768
+ /* @__PURE__ */ jsx(PhoneIcon, {}),
1769
+ "Phone"
1770
+ ]
1771
+ }
1772
+ )
1773
+ ] }),
1774
+ showEmailOnly && renderEmailField(),
1775
+ showPhoneOnly && renderPhoneField(),
1776
+ showBoth && /* @__PURE__ */ jsxs(Fragment, { children: [
1777
+ renderEmailField(),
1778
+ renderPhoneField()
1779
+ ] }),
1780
+ showChoice && /* @__PURE__ */ jsxs(Fragment, { children: [
1781
+ activeTab === "email" && renderEmailField(),
1782
+ activeTab === "phone" && renderPhoneField()
1783
+ ] }),
1784
+ /* @__PURE__ */ jsx("button", { type: "submit", class: "pp-prechat-submit", disabled: isSubmitting, children: isSubmitting ? "Submitting..." : "Start chatting" }),
1785
+ !config.required && /* @__PURE__ */ jsx("button", { type: "button", class: "pp-prechat-skip", onClick: onSkip, children: "Skip for now" })
1786
+ ] })
1787
+ ] });
1788
+ }
1789
+
1073
1790
  // src/components/ChatWidget.tsx
1074
- import { Fragment as Fragment2, jsx, jsxs } from "preact/jsx-runtime";
1791
+ import { Fragment as Fragment3, jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
1075
1792
  function formatDateSeparator(date) {
1076
1793
  const now = /* @__PURE__ */ new Date();
1077
1794
  const messageDate = new Date(date);
@@ -1091,28 +1808,33 @@ function getDateKey(date) {
1091
1808
  return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
1092
1809
  }
1093
1810
  function ChatWidget({ client: client2, config: initialConfig }) {
1094
- const [isOpen, setIsOpen] = useState(false);
1095
- const [messages, setMessages] = useState([]);
1096
- const [inputValue, setInputValue] = useState("");
1097
- const [isTyping, setIsTyping] = useState(false);
1098
- const [operatorOnline, setOperatorOnline] = useState(false);
1099
- const [isConnected, setIsConnected] = useState(false);
1100
- const [unreadCount, setUnreadCount] = useState(0);
1101
- const [pendingAttachments, setPendingAttachments] = useState([]);
1102
- const [isUploading, setIsUploading] = useState(false);
1103
- const [replyingTo, setReplyingTo] = useState(null);
1104
- const [editingMessage, setEditingMessage] = useState(null);
1105
- const [editContent, setEditContent] = useState("");
1106
- const [messageMenu, setMessageMenu] = useState(null);
1107
- const [isDragging, setIsDragging] = useState(false);
1108
- const [hoveredMessageId, setHoveredMessageId] = useState(null);
1109
- const [longPressTimer, setLongPressTimer] = useState(null);
1110
- const [config, setConfig] = useState(initialConfig);
1111
- const messagesEndRef = useRef(null);
1112
- const inputRef = useRef(null);
1113
- const fileInputRef = useRef(null);
1114
- const messagesContainerRef = useRef(null);
1115
- useEffect(() => {
1811
+ const [isOpen, setIsOpen] = useState2(false);
1812
+ const [messages, setMessages] = useState2([]);
1813
+ const [inputValue, setInputValue] = useState2("");
1814
+ const [isTyping, setIsTyping] = useState2(false);
1815
+ const [operatorOnline, setOperatorOnline] = useState2(false);
1816
+ const [isConnected, setIsConnected] = useState2(false);
1817
+ const [unreadCount, setUnreadCount] = useState2(0);
1818
+ const [pendingAttachments, setPendingAttachments] = useState2([]);
1819
+ const [isUploading, setIsUploading] = useState2(false);
1820
+ const [replyingTo, setReplyingTo] = useState2(null);
1821
+ const [editingMessage, setEditingMessage] = useState2(null);
1822
+ const [editContent, setEditContent] = useState2("");
1823
+ const [messageMenu, setMessageMenu] = useState2(null);
1824
+ const [isDragging, setIsDragging] = useState2(false);
1825
+ const [hoveredMessageId, setHoveredMessageId] = useState2(null);
1826
+ const [longPressTimer, setLongPressTimer] = useState2(null);
1827
+ const [swipedMessageId, setSwipedMessageId] = useState2(null);
1828
+ const [swipeOffset, setSwipeOffset] = useState2(0);
1829
+ const touchStartRef = useRef2(null);
1830
+ const [config, setConfig] = useState2(initialConfig);
1831
+ const [preChatForm, setPreChatForm] = useState2(void 0);
1832
+ const [preChatSkipped, setPreChatSkipped] = useState2(false);
1833
+ const messagesEndRef = useRef2(null);
1834
+ const inputRef = useRef2(null);
1835
+ const fileInputRef = useRef2(null);
1836
+ const messagesContainerRef = useRef2(null);
1837
+ useEffect2(() => {
1116
1838
  const unsubOpen = client2.on("openChange", setIsOpen);
1117
1839
  const unsubMessage = client2.on("message", () => {
1118
1840
  setMessages([...client2.getMessages()]);
@@ -1128,6 +1850,10 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1128
1850
  setMessages(client2.getMessages());
1129
1851
  setOperatorOnline(client2.getSession()?.operatorOnline ?? false);
1130
1852
  setConfig(client2.getConfig());
1853
+ setPreChatForm(client2.getSession()?.preChatForm);
1854
+ });
1855
+ const unsubPreChat = client2.on("preChatCompleted", () => {
1856
+ setPreChatForm((prev) => prev ? { ...prev, completed: true } : prev);
1131
1857
  });
1132
1858
  const unsubConfig = client2.on("configUpdate", () => {
1133
1859
  setConfig(client2.getConfig());
@@ -1137,6 +1863,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1137
1863
  setMessages(client2.getMessages());
1138
1864
  setOperatorOnline(client2.getSession()?.operatorOnline ?? false);
1139
1865
  setConfig(client2.getConfig());
1866
+ setPreChatForm(client2.getSession()?.preChatForm);
1140
1867
  }
1141
1868
  return () => {
1142
1869
  unsubOpen();
@@ -1144,15 +1871,16 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1144
1871
  unsubTyping();
1145
1872
  unsubPresence();
1146
1873
  unsubConnect();
1874
+ unsubPreChat();
1147
1875
  unsubConfig();
1148
1876
  };
1149
1877
  }, [client2]);
1150
- useEffect(() => {
1878
+ useEffect2(() => {
1151
1879
  if (isOpen) {
1152
1880
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
1153
1881
  }
1154
1882
  }, [messages, isOpen]);
1155
- useEffect(() => {
1883
+ useEffect2(() => {
1156
1884
  if (isOpen) {
1157
1885
  setTimeout(() => {
1158
1886
  messagesEndRef.current?.scrollIntoView({ behavior: "auto" });
@@ -1161,7 +1889,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1161
1889
  setUnreadCount(0);
1162
1890
  }
1163
1891
  }, [isOpen]);
1164
- useEffect(() => {
1892
+ useEffect2(() => {
1165
1893
  if (!isOpen && messages.length > 0) {
1166
1894
  const unread = messages.filter(
1167
1895
  (msg) => msg.sender !== "visitor" && msg.status !== "read"
@@ -1179,14 +1907,14 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1179
1907
  client2.sendReadStatus(messageIds, "read");
1180
1908
  }
1181
1909
  }, [isOpen, isConnected, messages, client2]);
1182
- useEffect(() => {
1910
+ useEffect2(() => {
1183
1911
  if (!isOpen || !isConnected) return;
1184
1912
  const timer = setTimeout(() => {
1185
1913
  markMessagesAsRead();
1186
1914
  }, 1e3);
1187
1915
  return () => clearTimeout(timer);
1188
1916
  }, [isOpen, isConnected, messages, markMessagesAsRead]);
1189
- useEffect(() => {
1917
+ useEffect2(() => {
1190
1918
  const handleVisibilityChange = () => {
1191
1919
  if (document.visibilityState === "visible" && isOpen) {
1192
1920
  markMessagesAsRead();
@@ -1195,7 +1923,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1195
1923
  document.addEventListener("visibilitychange", handleVisibilityChange);
1196
1924
  return () => document.removeEventListener("visibilitychange", handleVisibilityChange);
1197
1925
  }, [isOpen, markMessagesAsRead]);
1198
- useEffect(() => {
1926
+ useEffect2(() => {
1199
1927
  const unsubRead = client2.on(
1200
1928
  "read",
1201
1929
  () => {
@@ -1334,26 +2062,43 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1334
2062
  y: mouseEvent.clientY
1335
2063
  });
1336
2064
  };
1337
- const handleTouchStart = (message) => {
1338
- const timer = setTimeout(() => {
1339
- if (navigator.vibrate) navigator.vibrate(50);
1340
- setMessageMenu({
1341
- message,
1342
- x: window.innerWidth / 2 - 60,
1343
- // Center horizontally
1344
- y: window.innerHeight / 2 - 50
1345
- // Center vertically
1346
- });
1347
- }, 500);
1348
- setLongPressTimer(timer);
2065
+ const handleTouchStart = (e, message) => {
2066
+ const touch = e.touches[0];
2067
+ touchStartRef.current = { x: touch.clientX, y: touch.clientY, time: Date.now() };
2068
+ if (swipedMessageId && swipedMessageId !== message.id) {
2069
+ setSwipedMessageId(null);
2070
+ setSwipeOffset(0);
2071
+ }
1349
2072
  };
1350
- const handleTouchEnd = () => {
1351
- if (longPressTimer) {
1352
- clearTimeout(longPressTimer);
1353
- setLongPressTimer(null);
2073
+ const handleTouchMove = (e, message) => {
2074
+ if (!touchStartRef.current) return;
2075
+ const touch = e.touches[0];
2076
+ const deltaX = touch.clientX - touchStartRef.current.x;
2077
+ const deltaY = touch.clientY - touchStartRef.current.y;
2078
+ if (Math.abs(deltaY) > Math.abs(deltaX)) return;
2079
+ if (deltaX < 0) {
2080
+ const offset = Math.max(deltaX, -100);
2081
+ setSwipeOffset(offset);
2082
+ setSwipedMessageId(message.id);
1354
2083
  }
1355
2084
  };
1356
- useEffect(() => {
2085
+ const handleTouchEnd = (message) => {
2086
+ if (!touchStartRef.current) return;
2087
+ const elapsed = Date.now() - touchStartRef.current.time;
2088
+ if (swipeOffset < -50 || swipeOffset < -20 && elapsed < 200) {
2089
+ setSwipeOffset(-80);
2090
+ if (navigator.vibrate) navigator.vibrate(30);
2091
+ } else {
2092
+ setSwipeOffset(0);
2093
+ setSwipedMessageId(null);
2094
+ }
2095
+ touchStartRef.current = null;
2096
+ };
2097
+ const resetSwipe = () => {
2098
+ setSwipedMessageId(null);
2099
+ setSwipeOffset(0);
2100
+ };
2101
+ useEffect2(() => {
1357
2102
  if (!messageMenu) return;
1358
2103
  const handleClickOutside = () => setMessageMenu(null);
1359
2104
  document.addEventListener("click", handleClickOutside);
@@ -1369,7 +2114,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1369
2114
  }, 1500);
1370
2115
  }
1371
2116
  };
1372
- const dragCounterRef = useRef(0);
2117
+ const dragCounterRef = useRef2(0);
1373
2118
  const handleDragEnter = (e) => {
1374
2119
  e.preventDefault();
1375
2120
  e.stopPropagation();
@@ -1445,22 +2190,24 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1445
2190
  const theme = getTheme(config.theme ?? "auto");
1446
2191
  const primaryColor = config.primaryColor ?? "#6366f1";
1447
2192
  const actionIconColor = theme === "dark" ? "#9ca3af" : "#6b7280";
1448
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1449
- /* @__PURE__ */ jsx("style", { children: styles(primaryColor, theme) }),
1450
- /* @__PURE__ */ jsxs(
2193
+ const shouldShowPreChat = preChatForm && preChatForm.enabled && !preChatForm.completed && !preChatSkipped && // Before first message: show immediately
2194
+ (preChatForm.timing === "before-first-message" && messages.length === 0 || preChatForm.timing === "after-first-message" && messages.some((m) => m.sender === "visitor"));
2195
+ return /* @__PURE__ */ jsxs2(Fragment2, { children: [
2196
+ /* @__PURE__ */ jsx2("style", { children: styles(primaryColor, theme) }),
2197
+ /* @__PURE__ */ jsxs2(
1451
2198
  "button",
1452
2199
  {
1453
2200
  class: `pp-toggle pp-${position}`,
1454
2201
  onClick: () => client2.toggleOpen(),
1455
2202
  "aria-label": isOpen ? "Close chat" : "Open chat",
1456
2203
  children: [
1457
- isOpen ? /* @__PURE__ */ jsx(CloseIcon, {}) : /* @__PURE__ */ jsx(ChatIcon, {}),
1458
- !isOpen && unreadCount > 0 && /* @__PURE__ */ jsx("span", { class: "pp-unread-badge", children: unreadCount > 9 ? "9+" : unreadCount }),
1459
- !isOpen && unreadCount === 0 && operatorOnline && /* @__PURE__ */ jsx("span", { class: "pp-online-dot" })
2204
+ isOpen ? /* @__PURE__ */ jsx2(CloseIcon, {}) : /* @__PURE__ */ jsx2(ChatIcon, {}),
2205
+ !isOpen && unreadCount > 0 && /* @__PURE__ */ jsx2("span", { class: "pp-unread-badge", children: unreadCount > 9 ? "9+" : unreadCount }),
2206
+ !isOpen && unreadCount === 0 && operatorOnline && /* @__PURE__ */ jsx2("span", { class: "pp-online-dot" })
1460
2207
  ]
1461
2208
  }
1462
2209
  ),
1463
- isOpen && /* @__PURE__ */ jsxs(
2210
+ isOpen && /* @__PURE__ */ jsxs2(
1464
2211
  "div",
1465
2212
  {
1466
2213
  class: `pp-window pp-${position} pp-theme-${theme} ${isDragging ? "pp-dragging" : ""}`,
@@ -1469,36 +2216,49 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1469
2216
  onDragLeave: handleDragLeave,
1470
2217
  onDrop: handleDrop,
1471
2218
  children: [
1472
- isDragging && /* @__PURE__ */ jsxs("div", { class: "pp-drop-overlay", children: [
1473
- /* @__PURE__ */ jsx("div", { class: "pp-drop-icon", children: /* @__PURE__ */ jsx(AttachIcon, {}) }),
1474
- /* @__PURE__ */ jsx("div", { class: "pp-drop-text", children: "Drop files to upload" })
2219
+ isDragging && /* @__PURE__ */ jsxs2("div", { class: "pp-drop-overlay", children: [
2220
+ /* @__PURE__ */ jsx2("div", { class: "pp-drop-icon", children: /* @__PURE__ */ jsx2(AttachIcon, {}) }),
2221
+ /* @__PURE__ */ jsx2("div", { class: "pp-drop-text", children: "Drop files to upload" })
1475
2222
  ] }),
1476
- /* @__PURE__ */ jsxs("div", { class: "pp-header", children: [
1477
- /* @__PURE__ */ jsxs("div", { class: "pp-header-info", children: [
1478
- config.operatorAvatar && /* @__PURE__ */ jsx("img", { src: config.operatorAvatar, alt: "", class: "pp-avatar" }),
1479
- /* @__PURE__ */ jsxs("div", { children: [
1480
- /* @__PURE__ */ jsx("div", { class: "pp-header-title", children: config.operatorName ?? "Support" }),
1481
- /* @__PURE__ */ jsx("div", { class: "pp-header-status", children: operatorOnline ? /* @__PURE__ */ jsxs(Fragment2, { children: [
1482
- /* @__PURE__ */ jsx("span", { class: "pp-status-dot pp-online" }),
2223
+ /* @__PURE__ */ jsxs2("div", { class: "pp-header", children: [
2224
+ /* @__PURE__ */ jsxs2("div", { class: "pp-header-info", children: [
2225
+ config.operatorAvatar && /* @__PURE__ */ jsx2("img", { src: config.operatorAvatar, alt: "", class: "pp-avatar" }),
2226
+ /* @__PURE__ */ jsxs2("div", { children: [
2227
+ /* @__PURE__ */ jsx2("div", { class: "pp-header-title", children: config.operatorName ?? "Support" }),
2228
+ /* @__PURE__ */ jsx2("div", { class: "pp-header-status", children: operatorOnline ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
2229
+ /* @__PURE__ */ jsx2("span", { class: "pp-status-dot pp-online" }),
1483
2230
  " Online"
1484
- ] }) : /* @__PURE__ */ jsxs(Fragment2, { children: [
1485
- /* @__PURE__ */ jsx("span", { class: "pp-status-dot" }),
2231
+ ] }) : /* @__PURE__ */ jsxs2(Fragment3, { children: [
2232
+ /* @__PURE__ */ jsx2("span", { class: "pp-status-dot" }),
1486
2233
  " Away"
1487
2234
  ] }) })
1488
2235
  ] })
1489
2236
  ] }),
1490
- /* @__PURE__ */ jsx(
2237
+ /* @__PURE__ */ jsx2(
1491
2238
  "button",
1492
2239
  {
1493
2240
  class: "pp-close-btn",
1494
2241
  onClick: () => client2.setOpen(false),
1495
2242
  "aria-label": "Close chat",
1496
- children: /* @__PURE__ */ jsx(CloseIcon, {})
2243
+ children: /* @__PURE__ */ jsx2(CloseIcon, {})
1497
2244
  }
1498
2245
  )
1499
2246
  ] }),
1500
- /* @__PURE__ */ jsxs("div", { class: "pp-messages", ref: messagesContainerRef, children: [
1501
- config.welcomeMessage && messages.length === 0 && /* @__PURE__ */ jsx("div", { class: "pp-welcome", children: config.welcomeMessage }),
2247
+ shouldShowPreChat && preChatForm && /* @__PURE__ */ jsx2(
2248
+ PreChatForm,
2249
+ {
2250
+ client: client2,
2251
+ config: preChatForm,
2252
+ onComplete: () => {
2253
+ setPreChatForm((prev) => prev ? { ...prev, completed: true } : prev);
2254
+ },
2255
+ onSkip: () => {
2256
+ setPreChatSkipped(true);
2257
+ }
2258
+ }
2259
+ ),
2260
+ !shouldShowPreChat && /* @__PURE__ */ jsxs2("div", { class: "pp-messages", ref: messagesContainerRef, onClick: () => swipedMessageId && resetSwipe(), children: [
2261
+ config.welcomeMessage && messages.length === 0 && /* @__PURE__ */ jsx2("div", { class: "pp-welcome", children: config.welcomeMessage }),
1502
2262
  messages.map((msg, index) => {
1503
2263
  const isDeleted = !!msg.deletedAt;
1504
2264
  const isEdited = !!msg.editedAt;
@@ -1526,125 +2286,168 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1526
2286
  }
1527
2287
  const isHovered = hoveredMessageId === msg.id;
1528
2288
  const showActions = isHovered && !isDeleted;
1529
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1530
- showDateSeparator && /* @__PURE__ */ jsx("div", { class: "pp-date-separator", children: /* @__PURE__ */ jsx("span", { children: formatDateSeparator(msgDate) }) }),
1531
- /* @__PURE__ */ jsxs(
1532
- "div",
1533
- {
1534
- id: `pp-msg-${msg.id}`,
1535
- class: `pp-message pp-message-${msg.sender} ${isDeleted ? "pp-message-deleted" : ""}`,
1536
- onContextMenu: (e) => handleMessageContextMenu(e, msg),
1537
- onMouseEnter: () => setHoveredMessageId(msg.id),
1538
- onMouseLeave: () => setHoveredMessageId(null),
1539
- onTouchStart: () => handleTouchStart(msg),
1540
- onTouchEnd: handleTouchEnd,
1541
- onTouchCancel: handleTouchEnd,
1542
- children: [
1543
- showActions && /* @__PURE__ */ jsxs("div", { class: `pp-message-actions ${msg.sender === "visitor" ? "pp-actions-left" : "pp-actions-right"}`, children: [
1544
- /* @__PURE__ */ jsx(
1545
- "button",
1546
- {
1547
- class: "pp-action-btn",
1548
- onClick: () => handleReply(msg),
1549
- title: "Reply",
1550
- children: /* @__PURE__ */ jsx(ReplyIcon, { color: actionIconColor })
1551
- }
1552
- ),
1553
- msg.sender === "visitor" && /* @__PURE__ */ jsxs(Fragment2, { children: [
1554
- /* @__PURE__ */ jsx(
2289
+ const isSwiped = swipedMessageId === msg.id;
2290
+ const msgSwipeOffset = isSwiped ? swipeOffset : 0;
2291
+ return /* @__PURE__ */ jsxs2(Fragment2, { children: [
2292
+ showDateSeparator && /* @__PURE__ */ jsx2("div", { class: "pp-date-separator", children: /* @__PURE__ */ jsx2("span", { children: formatDateSeparator(msgDate) }) }),
2293
+ /* @__PURE__ */ jsxs2("div", { class: `pp-message-swipe-container ${msg.sender === "visitor" ? "pp-swipe-left" : "pp-swipe-right"}`, children: [
2294
+ /* @__PURE__ */ jsxs2("div", { class: "pp-swipe-actions", children: [
2295
+ /* @__PURE__ */ jsx2(
2296
+ "button",
2297
+ {
2298
+ class: "pp-swipe-action pp-swipe-reply",
2299
+ onClick: () => {
2300
+ handleReply(msg);
2301
+ resetSwipe();
2302
+ },
2303
+ children: /* @__PURE__ */ jsx2(ReplyIcon, { color: "#fff" })
2304
+ }
2305
+ ),
2306
+ msg.sender === "visitor" && !isDeleted && /* @__PURE__ */ jsxs2(Fragment3, { children: [
2307
+ /* @__PURE__ */ jsx2(
2308
+ "button",
2309
+ {
2310
+ class: "pp-swipe-action pp-swipe-edit",
2311
+ onClick: () => {
2312
+ handleStartEdit(msg);
2313
+ resetSwipe();
2314
+ },
2315
+ children: /* @__PURE__ */ jsx2(EditIcon, { color: "#fff" })
2316
+ }
2317
+ ),
2318
+ /* @__PURE__ */ jsx2(
2319
+ "button",
2320
+ {
2321
+ class: "pp-swipe-action pp-swipe-delete",
2322
+ onClick: () => {
2323
+ handleDelete(msg);
2324
+ resetSwipe();
2325
+ },
2326
+ children: /* @__PURE__ */ jsx2(DeleteIcon, { color: "#fff" })
2327
+ }
2328
+ )
2329
+ ] })
2330
+ ] }),
2331
+ /* @__PURE__ */ jsxs2(
2332
+ "div",
2333
+ {
2334
+ id: `pp-msg-${msg.id}`,
2335
+ class: `pp-message pp-message-${msg.sender} ${isDeleted ? "pp-message-deleted" : ""}`,
2336
+ style: { transform: `translateX(${msgSwipeOffset}px)`, transition: touchStartRef.current ? "none" : "transform 0.2s ease-out" },
2337
+ onContextMenu: (e) => handleMessageContextMenu(e, msg),
2338
+ onMouseEnter: () => setHoveredMessageId(msg.id),
2339
+ onMouseLeave: () => setHoveredMessageId(null),
2340
+ onTouchStart: (e) => handleTouchStart(e, msg),
2341
+ onTouchMove: (e) => handleTouchMove(e, msg),
2342
+ onTouchEnd: () => handleTouchEnd(msg),
2343
+ onTouchCancel: () => handleTouchEnd(msg),
2344
+ children: [
2345
+ showActions && /* @__PURE__ */ jsxs2("div", { class: `pp-message-actions ${msg.sender === "visitor" ? "pp-actions-left" : "pp-actions-right"}`, children: [
2346
+ /* @__PURE__ */ jsx2(
1555
2347
  "button",
1556
2348
  {
1557
2349
  class: "pp-action-btn",
1558
- onClick: () => handleStartEdit(msg),
1559
- title: "Edit",
1560
- children: /* @__PURE__ */ jsx(EditIcon, { color: actionIconColor })
2350
+ onClick: () => handleReply(msg),
2351
+ title: "Reply",
2352
+ children: /* @__PURE__ */ jsx2(ReplyIcon, { color: actionIconColor })
1561
2353
  }
1562
2354
  ),
1563
- /* @__PURE__ */ jsx(
1564
- "button",
1565
- {
1566
- class: "pp-action-btn pp-action-delete",
1567
- onClick: () => handleDelete(msg),
1568
- title: "Delete",
1569
- children: /* @__PURE__ */ jsx(DeleteIcon, { color: actionIconColor })
1570
- }
1571
- )
2355
+ msg.sender === "visitor" && /* @__PURE__ */ jsxs2(Fragment3, { children: [
2356
+ /* @__PURE__ */ jsx2(
2357
+ "button",
2358
+ {
2359
+ class: "pp-action-btn",
2360
+ onClick: () => handleStartEdit(msg),
2361
+ title: "Edit",
2362
+ children: /* @__PURE__ */ jsx2(EditIcon, { color: actionIconColor })
2363
+ }
2364
+ ),
2365
+ /* @__PURE__ */ jsx2(
2366
+ "button",
2367
+ {
2368
+ class: "pp-action-btn pp-action-delete",
2369
+ onClick: () => handleDelete(msg),
2370
+ title: "Delete",
2371
+ children: /* @__PURE__ */ jsx2(DeleteIcon, { color: actionIconColor })
2372
+ }
2373
+ )
2374
+ ] })
2375
+ ] }),
2376
+ replyData && (replyData.content || replyData.hasAttachment) && /* @__PURE__ */ jsxs2(
2377
+ "div",
2378
+ {
2379
+ class: "pp-reply-quote pp-reply-quote-clickable",
2380
+ onClick: () => scrollToMessage(replyData.id),
2381
+ role: "button",
2382
+ tabIndex: 0,
2383
+ onKeyDown: (e) => e.key === "Enter" && scrollToMessage(replyData.id),
2384
+ children: [
2385
+ /* @__PURE__ */ jsx2("span", { class: "pp-reply-sender", children: replyData.sender === "visitor" ? "You" : "Support" }),
2386
+ /* @__PURE__ */ jsx2("span", { class: "pp-reply-content", children: replyData.deleted ? "Message deleted" : /* @__PURE__ */ jsxs2(Fragment3, { children: [
2387
+ replyData.hasAttachment && /* @__PURE__ */ jsx2("span", { class: "pp-reply-attachment-icon", children: replyData.attachmentType?.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
2388
+ replyData.content ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
2389
+ (replyData.content || "").slice(0, 50),
2390
+ (replyData.content || "").length > 50 ? "..." : ""
2391
+ ] }) : replyData.attachmentType?.startsWith("image/") ? "Photo" : "File"
2392
+ ] }) })
2393
+ ]
2394
+ }
2395
+ ),
2396
+ isDeleted ? /* @__PURE__ */ jsxs2("div", { class: "pp-message-content pp-deleted-content", children: [
2397
+ /* @__PURE__ */ jsx2("span", { class: "pp-deleted-icon", children: "\u{1F5D1}\uFE0F" }),
2398
+ " Message deleted"
2399
+ ] }) : /* @__PURE__ */ jsxs2(Fragment3, { children: [
2400
+ msg.content && /* @__PURE__ */ jsx2("div", { class: "pp-message-content", children: msg.content }),
2401
+ msg.attachments && msg.attachments.length > 0 && /* @__PURE__ */ jsx2("div", { class: "pp-message-attachments", children: msg.attachments.map((att) => /* @__PURE__ */ jsx2(AttachmentDisplay, { attachment: att }, att.id)) })
2402
+ ] }),
2403
+ /* @__PURE__ */ jsxs2("div", { class: "pp-message-time", children: [
2404
+ formatTime(msg.timestamp),
2405
+ isEdited && !isDeleted && /* @__PURE__ */ jsx2("span", { class: "pp-edited-badge", children: "edited" }),
2406
+ msg.sender === "ai" && /* @__PURE__ */ jsx2("span", { class: "pp-ai-badge", children: "AI" }),
2407
+ msg.sender === "visitor" && !isDeleted && /* @__PURE__ */ jsx2("span", { class: `pp-status pp-status-${msg.status ?? "sent"}`, children: /* @__PURE__ */ jsx2(StatusIcon, { status: msg.status }) })
1572
2408
  ] })
1573
- ] }),
1574
- replyData && (replyData.content || replyData.hasAttachment) && /* @__PURE__ */ jsxs(
1575
- "div",
1576
- {
1577
- class: "pp-reply-quote pp-reply-quote-clickable",
1578
- onClick: () => scrollToMessage(replyData.id),
1579
- role: "button",
1580
- tabIndex: 0,
1581
- onKeyDown: (e) => e.key === "Enter" && scrollToMessage(replyData.id),
1582
- children: [
1583
- /* @__PURE__ */ jsx("span", { class: "pp-reply-sender", children: replyData.sender === "visitor" ? "You" : "Support" }),
1584
- /* @__PURE__ */ jsx("span", { class: "pp-reply-content", children: replyData.deleted ? "Message deleted" : /* @__PURE__ */ jsxs(Fragment2, { children: [
1585
- replyData.hasAttachment && /* @__PURE__ */ jsx("span", { class: "pp-reply-attachment-icon", children: replyData.attachmentType?.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
1586
- replyData.content ? /* @__PURE__ */ jsxs(Fragment2, { children: [
1587
- (replyData.content || "").slice(0, 50),
1588
- (replyData.content || "").length > 50 ? "..." : ""
1589
- ] }) : replyData.attachmentType?.startsWith("image/") ? "Photo" : "File"
1590
- ] }) })
1591
- ]
1592
- }
1593
- ),
1594
- isDeleted ? /* @__PURE__ */ jsxs("div", { class: "pp-message-content pp-deleted-content", children: [
1595
- /* @__PURE__ */ jsx("span", { class: "pp-deleted-icon", children: "\u{1F5D1}\uFE0F" }),
1596
- " Message deleted"
1597
- ] }) : /* @__PURE__ */ jsxs(Fragment2, { children: [
1598
- msg.content && /* @__PURE__ */ jsx("div", { class: "pp-message-content", children: msg.content }),
1599
- msg.attachments && msg.attachments.length > 0 && /* @__PURE__ */ jsx("div", { class: "pp-message-attachments", children: msg.attachments.map((att) => /* @__PURE__ */ jsx(AttachmentDisplay, { attachment: att }, att.id)) })
1600
- ] }),
1601
- /* @__PURE__ */ jsxs("div", { class: "pp-message-time", children: [
1602
- formatTime(msg.timestamp),
1603
- isEdited && !isDeleted && /* @__PURE__ */ jsx("span", { class: "pp-edited-badge", children: "edited" }),
1604
- msg.sender === "ai" && /* @__PURE__ */ jsx("span", { class: "pp-ai-badge", children: "AI" }),
1605
- msg.sender === "visitor" && !isDeleted && /* @__PURE__ */ jsx("span", { class: `pp-status pp-status-${msg.status ?? "sent"}`, children: /* @__PURE__ */ jsx(StatusIcon, { status: msg.status }) })
1606
- ] })
1607
- ]
1608
- }
1609
- )
2409
+ ]
2410
+ }
2411
+ )
2412
+ ] })
1610
2413
  ] }, msg.id);
1611
2414
  }),
1612
- isTyping && /* @__PURE__ */ jsxs("div", { class: "pp-message pp-message-operator pp-typing", children: [
1613
- /* @__PURE__ */ jsx("span", {}),
1614
- /* @__PURE__ */ jsx("span", {}),
1615
- /* @__PURE__ */ jsx("span", {})
2415
+ isTyping && /* @__PURE__ */ jsxs2("div", { class: "pp-message pp-message-operator pp-typing", children: [
2416
+ /* @__PURE__ */ jsx2("span", {}),
2417
+ /* @__PURE__ */ jsx2("span", {}),
2418
+ /* @__PURE__ */ jsx2("span", {})
1616
2419
  ] }),
1617
- /* @__PURE__ */ jsx("div", { ref: messagesEndRef })
2420
+ /* @__PURE__ */ jsx2("div", { ref: messagesEndRef })
1618
2421
  ] }),
1619
- messageMenu && /* @__PURE__ */ jsxs(
2422
+ messageMenu && /* @__PURE__ */ jsxs2(
1620
2423
  "div",
1621
2424
  {
1622
2425
  class: "pp-message-menu",
1623
2426
  style: { top: `${messageMenu.y}px`, left: `${messageMenu.x}px` },
1624
2427
  children: [
1625
- /* @__PURE__ */ jsxs("button", { onClick: () => handleReply(messageMenu.message), children: [
1626
- /* @__PURE__ */ jsx(ReplyIcon, { color: actionIconColor }),
2428
+ /* @__PURE__ */ jsxs2("button", { onClick: () => handleReply(messageMenu.message), children: [
2429
+ /* @__PURE__ */ jsx2(ReplyIcon, { color: actionIconColor }),
1627
2430
  " Reply"
1628
2431
  ] }),
1629
- messageMenu.message.sender === "visitor" && !messageMenu.message.deletedAt && /* @__PURE__ */ jsxs(Fragment2, { children: [
1630
- /* @__PURE__ */ jsxs("button", { onClick: () => handleStartEdit(messageMenu.message), children: [
1631
- /* @__PURE__ */ jsx(EditIcon, { color: actionIconColor }),
2432
+ messageMenu.message.sender === "visitor" && !messageMenu.message.deletedAt && /* @__PURE__ */ jsxs2(Fragment3, { children: [
2433
+ /* @__PURE__ */ jsxs2("button", { onClick: () => handleStartEdit(messageMenu.message), children: [
2434
+ /* @__PURE__ */ jsx2(EditIcon, { color: actionIconColor }),
1632
2435
  " Edit"
1633
2436
  ] }),
1634
- /* @__PURE__ */ jsxs("button", { class: "pp-menu-delete", onClick: () => handleDelete(messageMenu.message), children: [
1635
- /* @__PURE__ */ jsx(DeleteIcon, { color: "#ef4444" }),
2437
+ /* @__PURE__ */ jsxs2("button", { class: "pp-menu-delete", onClick: () => handleDelete(messageMenu.message), children: [
2438
+ /* @__PURE__ */ jsx2(DeleteIcon, { color: "#ef4444" }),
1636
2439
  " Delete"
1637
2440
  ] })
1638
2441
  ] })
1639
2442
  ]
1640
2443
  }
1641
2444
  ),
1642
- editingMessage && /* @__PURE__ */ jsxs("div", { class: "pp-edit-modal", children: [
1643
- /* @__PURE__ */ jsxs("div", { class: "pp-edit-header", children: [
1644
- /* @__PURE__ */ jsx("span", { children: "Edit message" }),
1645
- /* @__PURE__ */ jsx("button", { onClick: handleCancelEdit, children: /* @__PURE__ */ jsx(CloseIcon, {}) })
2445
+ editingMessage && /* @__PURE__ */ jsxs2("div", { class: "pp-edit-modal", children: [
2446
+ /* @__PURE__ */ jsxs2("div", { class: "pp-edit-header", children: [
2447
+ /* @__PURE__ */ jsx2("span", { children: "Edit message" }),
2448
+ /* @__PURE__ */ jsx2("button", { onClick: handleCancelEdit, children: /* @__PURE__ */ jsx2(CloseIcon, {}) })
1646
2449
  ] }),
1647
- /* @__PURE__ */ jsx(
2450
+ /* @__PURE__ */ jsx2(
1648
2451
  "textarea",
1649
2452
  {
1650
2453
  class: "pp-edit-input",
@@ -1653,41 +2456,41 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1653
2456
  autoFocus: true
1654
2457
  }
1655
2458
  ),
1656
- /* @__PURE__ */ jsxs("div", { class: "pp-edit-actions", children: [
1657
- /* @__PURE__ */ jsx("button", { class: "pp-edit-cancel", onClick: handleCancelEdit, children: "Cancel" }),
1658
- /* @__PURE__ */ jsx("button", { class: "pp-edit-save", onClick: handleSaveEdit, disabled: !editContent.trim(), children: "Save" })
2459
+ /* @__PURE__ */ jsxs2("div", { class: "pp-edit-actions", children: [
2460
+ /* @__PURE__ */ jsx2("button", { class: "pp-edit-cancel", onClick: handleCancelEdit, children: "Cancel" }),
2461
+ /* @__PURE__ */ jsx2("button", { class: "pp-edit-save", onClick: handleSaveEdit, disabled: !editContent.trim(), children: "Save" })
1659
2462
  ] })
1660
2463
  ] }),
1661
- replyingTo && /* @__PURE__ */ jsxs("div", { class: "pp-reply-preview", children: [
1662
- /* @__PURE__ */ jsxs("div", { class: "pp-reply-preview-content", children: [
1663
- /* @__PURE__ */ jsx("span", { class: "pp-reply-label", children: "Replying to" }),
1664
- /* @__PURE__ */ jsxs("span", { class: "pp-reply-text", children: [
1665
- replyingTo.attachments && replyingTo.attachments.length > 0 && /* @__PURE__ */ jsx("span", { class: "pp-reply-attachment-icon", children: replyingTo.attachments[0].mimeType.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
1666
- replyingTo.content ? /* @__PURE__ */ jsxs(Fragment2, { children: [
2464
+ replyingTo && /* @__PURE__ */ jsxs2("div", { class: "pp-reply-preview", children: [
2465
+ /* @__PURE__ */ jsxs2("div", { class: "pp-reply-preview-content", children: [
2466
+ /* @__PURE__ */ jsx2("span", { class: "pp-reply-label", children: "Replying to" }),
2467
+ /* @__PURE__ */ jsxs2("span", { class: "pp-reply-text", children: [
2468
+ replyingTo.attachments && replyingTo.attachments.length > 0 && /* @__PURE__ */ jsx2("span", { class: "pp-reply-attachment-icon", children: replyingTo.attachments[0].mimeType.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
2469
+ replyingTo.content ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
1667
2470
  replyingTo.content.slice(0, 50),
1668
2471
  replyingTo.content.length > 50 ? "..." : ""
1669
2472
  ] }) : replyingTo.attachments?.[0]?.mimeType.startsWith("image/") ? "Photo" : "File"
1670
2473
  ] })
1671
2474
  ] }),
1672
- /* @__PURE__ */ jsx("button", { class: "pp-reply-cancel", onClick: handleCancelReply, children: /* @__PURE__ */ jsx(CloseIcon, {}) })
2475
+ /* @__PURE__ */ jsx2("button", { class: "pp-reply-cancel", onClick: handleCancelReply, children: /* @__PURE__ */ jsx2(CloseIcon, {}) })
1673
2476
  ] }),
1674
- pendingAttachments.length > 0 && /* @__PURE__ */ jsx("div", { class: "pp-attachments-preview", children: pendingAttachments.map((pending) => /* @__PURE__ */ jsxs("div", { class: `pp-attachment-preview pp-attachment-${pending.status}`, children: [
1675
- pending.preview ? /* @__PURE__ */ jsx("img", { src: pending.preview, alt: pending.file.name, class: "pp-preview-img" }) : /* @__PURE__ */ jsx("div", { class: "pp-preview-file", children: /* @__PURE__ */ jsx(FileIcon, { mimeType: pending.file.type }) }),
1676
- /* @__PURE__ */ jsx(
2477
+ pendingAttachments.length > 0 && /* @__PURE__ */ jsx2("div", { class: "pp-attachments-preview", children: pendingAttachments.map((pending) => /* @__PURE__ */ jsxs2("div", { class: `pp-attachment-preview pp-attachment-${pending.status}`, children: [
2478
+ pending.preview ? /* @__PURE__ */ jsx2("img", { src: pending.preview, alt: pending.file.name, class: "pp-preview-img" }) : /* @__PURE__ */ jsx2("div", { class: "pp-preview-file", children: /* @__PURE__ */ jsx2(FileIcon, { mimeType: pending.file.type }) }),
2479
+ /* @__PURE__ */ jsx2(
1677
2480
  "button",
1678
2481
  {
1679
2482
  class: "pp-remove-attachment",
1680
2483
  onClick: () => handleRemoveAttachment(pending.id),
1681
2484
  "aria-label": "Remove attachment",
1682
2485
  type: "button",
1683
- children: /* @__PURE__ */ jsx(CloseIcon, {})
2486
+ children: /* @__PURE__ */ jsx2(CloseIcon, {})
1684
2487
  }
1685
2488
  ),
1686
- pending.status === "uploading" && /* @__PURE__ */ jsx("div", { class: "pp-upload-progress", style: { width: `${pending.progress}%` } }),
1687
- pending.status === "error" && /* @__PURE__ */ jsx("div", { class: "pp-upload-error", title: pending.error, children: "!" })
2489
+ pending.status === "uploading" && /* @__PURE__ */ jsx2("div", { class: "pp-upload-progress", style: { width: `${pending.progress}%` } }),
2490
+ pending.status === "error" && /* @__PURE__ */ jsx2("div", { class: "pp-upload-error", title: pending.error, children: "!" })
1688
2491
  ] }, pending.id)) }),
1689
- /* @__PURE__ */ jsxs("form", { class: "pp-input-form", onSubmit: handleSubmit, children: [
1690
- /* @__PURE__ */ jsx(
2492
+ !shouldShowPreChat && /* @__PURE__ */ jsxs2("form", { class: "pp-input-form", onSubmit: handleSubmit, children: [
2493
+ /* @__PURE__ */ jsx2(
1691
2494
  "input",
1692
2495
  {
1693
2496
  ref: (el) => {
@@ -1702,7 +2505,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1702
2505
  multiple: true
1703
2506
  }
1704
2507
  ),
1705
- /* @__PURE__ */ jsx(
2508
+ /* @__PURE__ */ jsx2(
1706
2509
  "button",
1707
2510
  {
1708
2511
  type: "button",
@@ -1710,10 +2513,10 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1710
2513
  onClick: () => fileInputRef.current?.click(),
1711
2514
  disabled: !isConnected || isUploading,
1712
2515
  "aria-label": "Attach file",
1713
- children: /* @__PURE__ */ jsx(AttachIcon, {})
2516
+ children: /* @__PURE__ */ jsx2(AttachIcon, {})
1714
2517
  }
1715
2518
  ),
1716
- /* @__PURE__ */ jsx(
2519
+ /* @__PURE__ */ jsx2(
1717
2520
  "input",
1718
2521
  {
1719
2522
  ref: inputRef,
@@ -1725,20 +2528,20 @@ function ChatWidget({ client: client2, config: initialConfig }) {
1725
2528
  disabled: !isConnected
1726
2529
  }
1727
2530
  ),
1728
- /* @__PURE__ */ jsx(
2531
+ /* @__PURE__ */ jsx2(
1729
2532
  "button",
1730
2533
  {
1731
2534
  type: "submit",
1732
2535
  class: "pp-send-btn",
1733
2536
  disabled: !inputValue.trim() && pendingAttachments.filter((a) => a.status === "ready").length === 0 || !isConnected || isUploading,
1734
2537
  "aria-label": "Send message",
1735
- children: /* @__PURE__ */ jsx(SendIcon, {})
2538
+ children: /* @__PURE__ */ jsx2(SendIcon, {})
1736
2539
  }
1737
2540
  )
1738
2541
  ] }),
1739
- /* @__PURE__ */ jsxs("div", { class: "pp-footer", children: [
2542
+ /* @__PURE__ */ jsxs2("div", { class: "pp-footer", children: [
1740
2543
  "Powered by ",
1741
- /* @__PURE__ */ jsx("a", { href: "https://pocketping.io", target: "_blank", rel: "noopener", children: "PocketPing" })
2544
+ /* @__PURE__ */ jsx2("a", { href: "https://pocketping.io", target: "_blank", rel: "noopener", children: "PocketPing" })
1742
2545
  ] })
1743
2546
  ]
1744
2547
  }
@@ -1766,90 +2569,90 @@ function formatTime(timestamp) {
1766
2569
  return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
1767
2570
  }
1768
2571
  function ChatIcon() {
1769
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: /* @__PURE__ */ jsx("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) });
2572
+ return /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: /* @__PURE__ */ jsx2("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) });
1770
2573
  }
1771
2574
  function CloseIcon() {
1772
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1773
- /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1774
- /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2575
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2576
+ /* @__PURE__ */ jsx2("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2577
+ /* @__PURE__ */ jsx2("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1775
2578
  ] });
1776
2579
  }
1777
2580
  function SendIcon() {
1778
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1779
- /* @__PURE__ */ jsx("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
1780
- /* @__PURE__ */ jsx("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
2581
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2582
+ /* @__PURE__ */ jsx2("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
2583
+ /* @__PURE__ */ jsx2("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
1781
2584
  ] });
1782
2585
  }
1783
2586
  function StatusIcon({ status }) {
1784
2587
  if (!status || status === "sending" || status === "sent") {
1785
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check", children: /* @__PURE__ */ jsx("polyline", { points: "3 8 7 12 13 4" }) });
2588
+ return /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check", children: /* @__PURE__ */ jsx2("polyline", { points: "3 8 7 12 13 4" }) });
1786
2589
  }
1787
2590
  if (status === "delivered") {
1788
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 20 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check-double", children: [
1789
- /* @__PURE__ */ jsx("polyline", { points: "1 8 5 12 11 4" }),
1790
- /* @__PURE__ */ jsx("polyline", { points: "7 8 11 12 17 4" })
2591
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 20 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check-double", children: [
2592
+ /* @__PURE__ */ jsx2("polyline", { points: "1 8 5 12 11 4" }),
2593
+ /* @__PURE__ */ jsx2("polyline", { points: "7 8 11 12 17 4" })
1791
2594
  ] });
1792
2595
  }
1793
2596
  if (status === "read") {
1794
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 20 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check-double pp-check-read", children: [
1795
- /* @__PURE__ */ jsx("polyline", { points: "1 8 5 12 11 4" }),
1796
- /* @__PURE__ */ jsx("polyline", { points: "7 8 11 12 17 4" })
2597
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 20 16", fill: "none", stroke: "currentColor", "stroke-width": "2", class: "pp-check-double pp-check-read", children: [
2598
+ /* @__PURE__ */ jsx2("polyline", { points: "1 8 5 12 11 4" }),
2599
+ /* @__PURE__ */ jsx2("polyline", { points: "7 8 11 12 17 4" })
1797
2600
  ] });
1798
2601
  }
1799
2602
  return null;
1800
2603
  }
1801
2604
  function AttachIcon() {
1802
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: /* @__PURE__ */ jsx("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
2605
+ return /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: /* @__PURE__ */ jsx2("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
1803
2606
  }
1804
2607
  function ReplyIcon({ color, size = 16 }) {
1805
2608
  const strokeColor = color || "currentColor";
1806
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: [
1807
- /* @__PURE__ */ jsx("polyline", { points: "9 17 4 12 9 7" }),
1808
- /* @__PURE__ */ jsx("path", { d: "M20 18v-2a4 4 0 0 0-4-4H4" })
2609
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: [
2610
+ /* @__PURE__ */ jsx2("polyline", { points: "9 17 4 12 9 7" }),
2611
+ /* @__PURE__ */ jsx2("path", { d: "M20 18v-2a4 4 0 0 0-4-4H4" })
1809
2612
  ] });
1810
2613
  }
1811
2614
  function EditIcon({ color, size = 16 }) {
1812
2615
  const strokeColor = color || "currentColor";
1813
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: /* @__PURE__ */ jsx("path", { d: "M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z" }) });
2616
+ return /* @__PURE__ */ jsx2("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: /* @__PURE__ */ jsx2("path", { d: "M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z" }) });
1814
2617
  }
1815
2618
  function DeleteIcon({ color, size = 16 }) {
1816
2619
  const strokeColor = color || "currentColor";
1817
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: [
1818
- /* @__PURE__ */ jsx("polyline", { points: "3 6 5 6 21 6" }),
1819
- /* @__PURE__ */ jsx("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
2620
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: [
2621
+ /* @__PURE__ */ jsx2("polyline", { points: "3 6 5 6 21 6" }),
2622
+ /* @__PURE__ */ jsx2("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
1820
2623
  ] });
1821
2624
  }
1822
2625
  function FileIcon({ mimeType }) {
1823
2626
  if (mimeType === "application/pdf") {
1824
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1825
- /* @__PURE__ */ jsx("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1826
- /* @__PURE__ */ jsx("polyline", { points: "14 2 14 8 20 8" }),
1827
- /* @__PURE__ */ jsx("path", { d: "M9 15h6" }),
1828
- /* @__PURE__ */ jsx("path", { d: "M9 11h6" })
2627
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2628
+ /* @__PURE__ */ jsx2("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
2629
+ /* @__PURE__ */ jsx2("polyline", { points: "14 2 14 8 20 8" }),
2630
+ /* @__PURE__ */ jsx2("path", { d: "M9 15h6" }),
2631
+ /* @__PURE__ */ jsx2("path", { d: "M9 11h6" })
1829
2632
  ] });
1830
2633
  }
1831
2634
  if (mimeType.startsWith("audio/")) {
1832
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1833
- /* @__PURE__ */ jsx("path", { d: "M9 18V5l12-2v13" }),
1834
- /* @__PURE__ */ jsx("circle", { cx: "6", cy: "18", r: "3" }),
1835
- /* @__PURE__ */ jsx("circle", { cx: "18", cy: "16", r: "3" })
2635
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2636
+ /* @__PURE__ */ jsx2("path", { d: "M9 18V5l12-2v13" }),
2637
+ /* @__PURE__ */ jsx2("circle", { cx: "6", cy: "18", r: "3" }),
2638
+ /* @__PURE__ */ jsx2("circle", { cx: "18", cy: "16", r: "3" })
1836
2639
  ] });
1837
2640
  }
1838
2641
  if (mimeType.startsWith("video/")) {
1839
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1840
- /* @__PURE__ */ jsx("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2.18", ry: "2.18" }),
1841
- /* @__PURE__ */ jsx("line", { x1: "7", y1: "2", x2: "7", y2: "22" }),
1842
- /* @__PURE__ */ jsx("line", { x1: "17", y1: "2", x2: "17", y2: "22" }),
1843
- /* @__PURE__ */ jsx("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
1844
- /* @__PURE__ */ jsx("line", { x1: "2", y1: "7", x2: "7", y2: "7" }),
1845
- /* @__PURE__ */ jsx("line", { x1: "2", y1: "17", x2: "7", y2: "17" }),
1846
- /* @__PURE__ */ jsx("line", { x1: "17", y1: "17", x2: "22", y2: "17" }),
1847
- /* @__PURE__ */ jsx("line", { x1: "17", y1: "7", x2: "22", y2: "7" })
2642
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2643
+ /* @__PURE__ */ jsx2("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2.18", ry: "2.18" }),
2644
+ /* @__PURE__ */ jsx2("line", { x1: "7", y1: "2", x2: "7", y2: "22" }),
2645
+ /* @__PURE__ */ jsx2("line", { x1: "17", y1: "2", x2: "17", y2: "22" }),
2646
+ /* @__PURE__ */ jsx2("line", { x1: "2", y1: "12", x2: "22", y2: "12" }),
2647
+ /* @__PURE__ */ jsx2("line", { x1: "2", y1: "7", x2: "7", y2: "7" }),
2648
+ /* @__PURE__ */ jsx2("line", { x1: "2", y1: "17", x2: "7", y2: "17" }),
2649
+ /* @__PURE__ */ jsx2("line", { x1: "17", y1: "17", x2: "22", y2: "17" }),
2650
+ /* @__PURE__ */ jsx2("line", { x1: "17", y1: "7", x2: "22", y2: "7" })
1848
2651
  ] });
1849
2652
  }
1850
- return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
1851
- /* @__PURE__ */ jsx("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1852
- /* @__PURE__ */ jsx("polyline", { points: "14 2 14 8 20 8" })
2653
+ return /* @__PURE__ */ jsxs2("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: [
2654
+ /* @__PURE__ */ jsx2("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
2655
+ /* @__PURE__ */ jsx2("polyline", { points: "14 2 14 8 20 8" })
1853
2656
  ] });
1854
2657
  }
1855
2658
  function AttachmentDisplay({ attachment }) {
@@ -1862,22 +2665,22 @@ function AttachmentDisplay({ attachment }) {
1862
2665
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
1863
2666
  };
1864
2667
  if (isImage) {
1865
- return /* @__PURE__ */ jsx("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-image", children: /* @__PURE__ */ jsx("img", { src: attachment.thumbnailUrl || attachment.url, alt: attachment.filename }) });
2668
+ return /* @__PURE__ */ jsx2("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-image", children: /* @__PURE__ */ jsx2("img", { src: attachment.thumbnailUrl || attachment.url, alt: attachment.filename }) });
1866
2669
  }
1867
2670
  if (isAudio) {
1868
- return /* @__PURE__ */ jsxs("div", { class: "pp-attachment pp-attachment-audio", children: [
1869
- /* @__PURE__ */ jsx("audio", { controls: true, preload: "metadata", children: /* @__PURE__ */ jsx("source", { src: attachment.url, type: attachment.mimeType }) }),
1870
- /* @__PURE__ */ jsx("span", { class: "pp-attachment-name", children: attachment.filename })
2671
+ return /* @__PURE__ */ jsxs2("div", { class: "pp-attachment pp-attachment-audio", children: [
2672
+ /* @__PURE__ */ jsx2("audio", { controls: true, preload: "metadata", children: /* @__PURE__ */ jsx2("source", { src: attachment.url, type: attachment.mimeType }) }),
2673
+ /* @__PURE__ */ jsx2("span", { class: "pp-attachment-name", children: attachment.filename })
1871
2674
  ] });
1872
2675
  }
1873
2676
  if (isVideo) {
1874
- return /* @__PURE__ */ jsx("div", { class: "pp-attachment pp-attachment-video", children: /* @__PURE__ */ jsx("video", { controls: true, preload: "metadata", children: /* @__PURE__ */ jsx("source", { src: attachment.url, type: attachment.mimeType }) }) });
2677
+ return /* @__PURE__ */ jsx2("div", { class: "pp-attachment pp-attachment-video", children: /* @__PURE__ */ jsx2("video", { controls: true, preload: "metadata", children: /* @__PURE__ */ jsx2("source", { src: attachment.url, type: attachment.mimeType }) }) });
1875
2678
  }
1876
- return /* @__PURE__ */ jsxs("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-file", children: [
1877
- /* @__PURE__ */ jsx(FileIcon, { mimeType: attachment.mimeType }),
1878
- /* @__PURE__ */ jsxs("div", { class: "pp-attachment-info", children: [
1879
- /* @__PURE__ */ jsx("span", { class: "pp-attachment-name", children: attachment.filename }),
1880
- /* @__PURE__ */ jsx("span", { class: "pp-attachment-size", children: formatSize(attachment.size) })
2679
+ return /* @__PURE__ */ jsxs2("a", { href: attachment.url, target: "_blank", rel: "noopener", class: "pp-attachment pp-attachment-file", children: [
2680
+ /* @__PURE__ */ jsx2(FileIcon, { mimeType: attachment.mimeType }),
2681
+ /* @__PURE__ */ jsxs2("div", { class: "pp-attachment-info", children: [
2682
+ /* @__PURE__ */ jsx2("span", { class: "pp-attachment-name", children: attachment.filename }),
2683
+ /* @__PURE__ */ jsx2("span", { class: "pp-attachment-size", children: formatSize(attachment.size) })
1881
2684
  ] })
1882
2685
  ] });
1883
2686
  }
@@ -1943,7 +2746,8 @@ var PocketPingClient = class {
1943
2746
  visitorId: response.visitorId,
1944
2747
  operatorOnline: response.operatorOnline ?? false,
1945
2748
  messages: response.messages ?? [],
1946
- identity: response.identity || storedIdentity || void 0
2749
+ identity: response.identity || storedIdentity || void 0,
2750
+ preChatForm: response.preChatForm
1947
2751
  };
1948
2752
  if (response.operatorName) {
1949
2753
  this.config.operatorName = response.operatorName;
@@ -2299,6 +3103,36 @@ var PocketPingClient = class {
2299
3103
  }
2300
3104
  }
2301
3105
  }
3106
+ /**
3107
+ * Submit pre-chat form data (email and/or phone)
3108
+ * @param data - Form data containing email and/or phone
3109
+ */
3110
+ async submitPreChat(data) {
3111
+ if (!this.session) {
3112
+ throw new Error("[PocketPing] Not connected");
3113
+ }
3114
+ if (!data.email && !data.phone) {
3115
+ throw new Error("[PocketPing] Either email or phone is required");
3116
+ }
3117
+ try {
3118
+ await this.fetch("/prechat", {
3119
+ method: "POST",
3120
+ body: JSON.stringify({
3121
+ sessionId: this.session.sessionId,
3122
+ email: data.email,
3123
+ phone: data.phone,
3124
+ phoneCountry: data.phoneCountry
3125
+ })
3126
+ });
3127
+ if (this.session.preChatForm) {
3128
+ this.session.preChatForm.completed = true;
3129
+ }
3130
+ this.emit("preChatCompleted", data);
3131
+ } catch (err) {
3132
+ console.error("[PocketPing] Failed to submit pre-chat form:", err);
3133
+ throw err;
3134
+ }
3135
+ }
2302
3136
  /**
2303
3137
  * Reset the user identity and optionally start a new session
2304
3138
  * Call on user logout to clear user data
@@ -2948,6 +3782,12 @@ var PocketPingClient = class {
2948
3782
  this.session.messages.push(message);
2949
3783
  this.emit("message", message);
2950
3784
  this.config.onMessage?.(message);
3785
+ if (message.sender !== "visitor" && !this.isOpen) {
3786
+ const autoOpen = this.config.autoOpenOnMessage ?? true;
3787
+ if (autoOpen) {
3788
+ this.setOpen(true);
3789
+ }
3790
+ }
2951
3791
  }
2952
3792
  }
2953
3793
  if (message.sender !== "visitor") {
@@ -3106,6 +3946,12 @@ var PocketPingClient = class {
3106
3946
  this.session.messages.push(message);
3107
3947
  this.emit("message", message);
3108
3948
  this.config.onMessage?.(message);
3949
+ if (message.sender !== "visitor" && !this.isOpen) {
3950
+ const autoOpen = this.config.autoOpenOnMessage ?? true;
3951
+ if (autoOpen) {
3952
+ this.setOpen(true);
3953
+ }
3954
+ }
3109
3955
  }
3110
3956
  }
3111
3957
  } catch (err) {