@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/README.md +2 -0
- package/dist/index.cjs +1198 -276
- package/dist/index.d.cts +28 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +1198 -276
- package/dist/pocketping.min.global.js +517 -83
- package/package.json +2 -1
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;
|
|
@@ -148,7 +159,7 @@ function styles(primaryColor, theme) {
|
|
|
148
159
|
display: flex;
|
|
149
160
|
align-items: center;
|
|
150
161
|
justify-content: space-between;
|
|
151
|
-
padding:
|
|
162
|
+
padding: 12px 14px;
|
|
152
163
|
background: ${primaryColor};
|
|
153
164
|
color: white;
|
|
154
165
|
}
|
|
@@ -156,24 +167,24 @@ function styles(primaryColor, theme) {
|
|
|
156
167
|
.pp-header-info {
|
|
157
168
|
display: flex;
|
|
158
169
|
align-items: center;
|
|
159
|
-
gap:
|
|
170
|
+
gap: 10px;
|
|
160
171
|
}
|
|
161
172
|
|
|
162
173
|
.pp-avatar {
|
|
163
|
-
width:
|
|
164
|
-
height:
|
|
174
|
+
width: 36px;
|
|
175
|
+
height: 36px;
|
|
165
176
|
border-radius: 50%;
|
|
166
177
|
object-fit: cover;
|
|
167
178
|
}
|
|
168
179
|
|
|
169
180
|
.pp-header-title {
|
|
170
181
|
font-weight: 600;
|
|
171
|
-
font-size:
|
|
182
|
+
font-size: 15px;
|
|
172
183
|
}
|
|
173
184
|
|
|
174
185
|
.pp-header-status {
|
|
175
|
-
font-size:
|
|
176
|
-
opacity: 0.
|
|
186
|
+
font-size: 11px;
|
|
187
|
+
opacity: 0.85;
|
|
177
188
|
display: flex;
|
|
178
189
|
align-items: center;
|
|
179
190
|
gap: 4px;
|
|
@@ -219,10 +230,14 @@ function styles(primaryColor, theme) {
|
|
|
219
230
|
.pp-messages {
|
|
220
231
|
flex: 1;
|
|
221
232
|
overflow-y: auto;
|
|
222
|
-
padding:
|
|
233
|
+
padding: 32px 12px 12px 12px;
|
|
223
234
|
display: flex;
|
|
224
235
|
flex-direction: column;
|
|
225
|
-
gap:
|
|
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 {
|
|
@@ -232,20 +247,110 @@ function styles(primaryColor, theme) {
|
|
|
232
247
|
font-size: 13px;
|
|
233
248
|
}
|
|
234
249
|
|
|
250
|
+
.pp-date-separator {
|
|
251
|
+
display: flex;
|
|
252
|
+
align-items: center;
|
|
253
|
+
justify-content: center;
|
|
254
|
+
margin: 16px 0 12px;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.pp-date-separator span {
|
|
258
|
+
background: ${colors.bgSecondary};
|
|
259
|
+
color: ${colors.textSecondary};
|
|
260
|
+
font-size: 11px;
|
|
261
|
+
padding: 4px 12px;
|
|
262
|
+
border-radius: 12px;
|
|
263
|
+
font-weight: 500;
|
|
264
|
+
}
|
|
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
|
+
|
|
235
335
|
.pp-message {
|
|
236
|
-
max-width:
|
|
237
|
-
padding: 10px
|
|
238
|
-
border-radius:
|
|
336
|
+
max-width: 85%;
|
|
337
|
+
padding: 6px 10px;
|
|
338
|
+
border-radius: 12px;
|
|
239
339
|
word-wrap: break-word;
|
|
240
340
|
position: relative;
|
|
241
341
|
user-select: text;
|
|
242
342
|
-webkit-user-select: text;
|
|
343
|
+
font-size: 14px;
|
|
344
|
+
line-height: 1.35;
|
|
345
|
+
display: flex;
|
|
346
|
+
flex-direction: column;
|
|
347
|
+
will-change: transform;
|
|
243
348
|
}
|
|
244
349
|
|
|
245
350
|
/* Hover actions container - positioned above message (Slack style) */
|
|
246
351
|
.pp-message-actions {
|
|
247
352
|
position: absolute;
|
|
248
|
-
top: -
|
|
353
|
+
top: -32px;
|
|
249
354
|
display: flex;
|
|
250
355
|
gap: 2px;
|
|
251
356
|
background: ${colors.bg};
|
|
@@ -258,6 +363,8 @@ function styles(primaryColor, theme) {
|
|
|
258
363
|
z-index: 10;
|
|
259
364
|
/* Reset color inheritance from message */
|
|
260
365
|
color: ${colors.textSecondary};
|
|
366
|
+
/* Ensure actions don't interfere with layout */
|
|
367
|
+
pointer-events: auto;
|
|
261
368
|
}
|
|
262
369
|
|
|
263
370
|
@keyframes pp-actions-fade-in {
|
|
@@ -331,7 +438,8 @@ function styles(primaryColor, theme) {
|
|
|
331
438
|
align-self: flex-end;
|
|
332
439
|
background: ${primaryColor};
|
|
333
440
|
color: white;
|
|
334
|
-
border-bottom-right-radius:
|
|
441
|
+
border-bottom-right-radius: 3px;
|
|
442
|
+
margin-left: 32px;
|
|
335
443
|
}
|
|
336
444
|
|
|
337
445
|
.pp-message-operator,
|
|
@@ -339,19 +447,32 @@ function styles(primaryColor, theme) {
|
|
|
339
447
|
align-self: flex-start;
|
|
340
448
|
background: ${colors.messageBg};
|
|
341
449
|
color: ${colors.text};
|
|
342
|
-
border-bottom-left-radius:
|
|
450
|
+
border-bottom-left-radius: 3px;
|
|
451
|
+
margin-right: 32px;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/* Add spacing between different senders */
|
|
455
|
+
.pp-message-visitor + .pp-message-operator,
|
|
456
|
+
.pp-message-visitor + .pp-message-ai,
|
|
457
|
+
.pp-message-operator + .pp-message-visitor,
|
|
458
|
+
.pp-message-ai + .pp-message-visitor {
|
|
459
|
+
margin-top: 8px;
|
|
343
460
|
}
|
|
344
461
|
|
|
345
462
|
.pp-message-content {
|
|
346
|
-
|
|
463
|
+
display: block;
|
|
464
|
+
flex: 1;
|
|
347
465
|
}
|
|
348
466
|
|
|
349
467
|
.pp-message-time {
|
|
350
|
-
font-size:
|
|
351
|
-
opacity: 0.
|
|
468
|
+
font-size: 10px;
|
|
469
|
+
opacity: 0.6;
|
|
352
470
|
display: flex;
|
|
353
471
|
align-items: center;
|
|
354
|
-
gap:
|
|
472
|
+
gap: 3px;
|
|
473
|
+
justify-content: flex-end;
|
|
474
|
+
margin-top: 8px;
|
|
475
|
+
flex-shrink: 0;
|
|
355
476
|
}
|
|
356
477
|
|
|
357
478
|
.pp-ai-badge {
|
|
@@ -388,13 +509,13 @@ function styles(primaryColor, theme) {
|
|
|
388
509
|
|
|
389
510
|
.pp-typing {
|
|
390
511
|
display: flex;
|
|
391
|
-
gap:
|
|
392
|
-
padding:
|
|
512
|
+
gap: 3px;
|
|
513
|
+
padding: 8px 12px;
|
|
393
514
|
}
|
|
394
515
|
|
|
395
516
|
.pp-typing span {
|
|
396
|
-
width:
|
|
397
|
-
height:
|
|
517
|
+
width: 6px;
|
|
518
|
+
height: 6px;
|
|
398
519
|
background: ${colors.textSecondary};
|
|
399
520
|
border-radius: 50%;
|
|
400
521
|
animation: pp-bounce 1.4s infinite ease-in-out both;
|
|
@@ -410,14 +531,18 @@ function styles(primaryColor, theme) {
|
|
|
410
531
|
|
|
411
532
|
.pp-input-form {
|
|
412
533
|
display: flex;
|
|
413
|
-
padding: 12px;
|
|
534
|
+
padding: 10px 12px;
|
|
414
535
|
gap: 8px;
|
|
415
536
|
border-top: 1px solid ${colors.border};
|
|
537
|
+
align-items: center;
|
|
416
538
|
}
|
|
417
539
|
|
|
418
540
|
.pp-input {
|
|
419
541
|
flex: 1;
|
|
420
|
-
|
|
542
|
+
min-width: 0;
|
|
543
|
+
height: 40px;
|
|
544
|
+
line-height: 40px;
|
|
545
|
+
padding: 0 16px;
|
|
421
546
|
border: 1px solid ${colors.border};
|
|
422
547
|
border-radius: 20px;
|
|
423
548
|
background: ${colors.bg};
|
|
@@ -425,6 +550,8 @@ function styles(primaryColor, theme) {
|
|
|
425
550
|
font-size: 14px;
|
|
426
551
|
outline: none;
|
|
427
552
|
transition: border-color 0.2s;
|
|
553
|
+
box-sizing: border-box;
|
|
554
|
+
margin: 0;
|
|
428
555
|
}
|
|
429
556
|
|
|
430
557
|
.pp-input:focus {
|
|
@@ -438,6 +565,7 @@ function styles(primaryColor, theme) {
|
|
|
438
565
|
.pp-send-btn {
|
|
439
566
|
width: 40px;
|
|
440
567
|
height: 40px;
|
|
568
|
+
min-width: 40px;
|
|
441
569
|
border-radius: 50%;
|
|
442
570
|
background: ${primaryColor};
|
|
443
571
|
color: white;
|
|
@@ -446,7 +574,18 @@ function styles(primaryColor, theme) {
|
|
|
446
574
|
display: flex;
|
|
447
575
|
align-items: center;
|
|
448
576
|
justify-content: center;
|
|
449
|
-
transition: opacity 0.2s;
|
|
577
|
+
transition: opacity 0.2s, transform 0.1s;
|
|
578
|
+
flex-shrink: 0;
|
|
579
|
+
margin: 0;
|
|
580
|
+
padding: 0;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
.pp-send-btn:not(:disabled):hover {
|
|
584
|
+
transform: scale(1.05);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
.pp-send-btn:not(:disabled):active {
|
|
588
|
+
transform: scale(0.95);
|
|
450
589
|
}
|
|
451
590
|
|
|
452
591
|
.pp-send-btn:disabled {
|
|
@@ -465,6 +604,7 @@ function styles(primaryColor, theme) {
|
|
|
465
604
|
font-size: 11px;
|
|
466
605
|
color: ${colors.textSecondary};
|
|
467
606
|
border-top: 1px solid ${colors.border};
|
|
607
|
+
opacity: 0.7;
|
|
468
608
|
}
|
|
469
609
|
|
|
470
610
|
.pp-footer a {
|
|
@@ -493,6 +633,7 @@ function styles(primaryColor, theme) {
|
|
|
493
633
|
.pp-attach-btn {
|
|
494
634
|
width: 40px;
|
|
495
635
|
height: 40px;
|
|
636
|
+
min-width: 40px;
|
|
496
637
|
border-radius: 50%;
|
|
497
638
|
background: transparent;
|
|
498
639
|
color: ${colors.textSecondary};
|
|
@@ -501,6 +642,8 @@ function styles(primaryColor, theme) {
|
|
|
501
642
|
display: flex;
|
|
502
643
|
align-items: center;
|
|
503
644
|
justify-content: center;
|
|
645
|
+
margin: 0;
|
|
646
|
+
padding: 0;
|
|
504
647
|
transition: color 0.2s, border-color 0.2s;
|
|
505
648
|
flex-shrink: 0;
|
|
506
649
|
}
|
|
@@ -621,7 +764,10 @@ function styles(primaryColor, theme) {
|
|
|
621
764
|
display: flex;
|
|
622
765
|
flex-direction: column;
|
|
623
766
|
gap: 8px;
|
|
624
|
-
margin-top:
|
|
767
|
+
margin-top: 6px;
|
|
768
|
+
max-width: 100%;
|
|
769
|
+
align-items: flex-start;
|
|
770
|
+
flex-shrink: 0;
|
|
625
771
|
}
|
|
626
772
|
|
|
627
773
|
.pp-attachment {
|
|
@@ -632,11 +778,22 @@ function styles(primaryColor, theme) {
|
|
|
632
778
|
overflow: hidden;
|
|
633
779
|
}
|
|
634
780
|
|
|
781
|
+
.pp-attachment-image,
|
|
782
|
+
.pp-attachment-video,
|
|
783
|
+
.pp-attachment-audio {
|
|
784
|
+
width: 240px;
|
|
785
|
+
max-width: 100%;
|
|
786
|
+
}
|
|
787
|
+
|
|
635
788
|
.pp-attachment-image img {
|
|
636
|
-
|
|
789
|
+
width: 100% !important;
|
|
790
|
+
height: auto !important;
|
|
791
|
+
max-width: 240px;
|
|
637
792
|
max-height: 200px;
|
|
638
793
|
border-radius: 8px;
|
|
639
794
|
display: block;
|
|
795
|
+
object-fit: cover !important;
|
|
796
|
+
object-position: center;
|
|
640
797
|
}
|
|
641
798
|
|
|
642
799
|
.pp-attachment-audio {
|
|
@@ -646,7 +803,8 @@ function styles(primaryColor, theme) {
|
|
|
646
803
|
}
|
|
647
804
|
|
|
648
805
|
.pp-attachment-audio audio {
|
|
649
|
-
width:
|
|
806
|
+
width: 240px;
|
|
807
|
+
max-width: 100%;
|
|
650
808
|
height: 36px;
|
|
651
809
|
}
|
|
652
810
|
|
|
@@ -656,14 +814,18 @@ function styles(primaryColor, theme) {
|
|
|
656
814
|
white-space: nowrap;
|
|
657
815
|
overflow: hidden;
|
|
658
816
|
text-overflow: ellipsis;
|
|
659
|
-
max-width:
|
|
817
|
+
max-width: 100%;
|
|
660
818
|
}
|
|
661
819
|
|
|
662
820
|
.pp-attachment-video video {
|
|
663
|
-
|
|
664
|
-
|
|
821
|
+
width: 100% !important;
|
|
822
|
+
height: auto !important;
|
|
823
|
+
max-width: 240px;
|
|
824
|
+
max-height: none;
|
|
665
825
|
border-radius: 8px;
|
|
666
826
|
display: block;
|
|
827
|
+
object-fit: contain !important;
|
|
828
|
+
object-position: center;
|
|
667
829
|
}
|
|
668
830
|
|
|
669
831
|
.pp-attachment-file {
|
|
@@ -1014,34 +1176,665 @@ function styles(primaryColor, theme) {
|
|
|
1014
1176
|
margin-left: 4px;
|
|
1015
1177
|
font-style: italic;
|
|
1016
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
|
+
}
|
|
1017
1446
|
`;
|
|
1018
1447
|
}
|
|
1019
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
|
+
|
|
1020
1790
|
// src/components/ChatWidget.tsx
|
|
1021
|
-
import { Fragment as
|
|
1791
|
+
import { Fragment as Fragment3, jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
|
|
1792
|
+
function formatDateSeparator(date) {
|
|
1793
|
+
const now = /* @__PURE__ */ new Date();
|
|
1794
|
+
const messageDate = new Date(date);
|
|
1795
|
+
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
1796
|
+
const msgDay = new Date(messageDate.getFullYear(), messageDate.getMonth(), messageDate.getDate());
|
|
1797
|
+
const diffDays = Math.floor((today.getTime() - msgDay.getTime()) / (1e3 * 60 * 60 * 24));
|
|
1798
|
+
if (diffDays === 0) return "Today";
|
|
1799
|
+
if (diffDays === 1) return "Yesterday";
|
|
1800
|
+
return messageDate.toLocaleDateString("en-US", {
|
|
1801
|
+
month: "short",
|
|
1802
|
+
day: "numeric",
|
|
1803
|
+
year: messageDate.getFullYear() !== now.getFullYear() ? "numeric" : void 0
|
|
1804
|
+
});
|
|
1805
|
+
}
|
|
1806
|
+
function getDateKey(date) {
|
|
1807
|
+
const d = new Date(date);
|
|
1808
|
+
return `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
|
|
1809
|
+
}
|
|
1022
1810
|
function ChatWidget({ client: client2, config: initialConfig }) {
|
|
1023
|
-
const [isOpen, setIsOpen] =
|
|
1024
|
-
const [messages, setMessages] =
|
|
1025
|
-
const [inputValue, setInputValue] =
|
|
1026
|
-
const [isTyping, setIsTyping] =
|
|
1027
|
-
const [operatorOnline, setOperatorOnline] =
|
|
1028
|
-
const [isConnected, setIsConnected] =
|
|
1029
|
-
const [unreadCount, setUnreadCount] =
|
|
1030
|
-
const [pendingAttachments, setPendingAttachments] =
|
|
1031
|
-
const [isUploading, setIsUploading] =
|
|
1032
|
-
const [replyingTo, setReplyingTo] =
|
|
1033
|
-
const [editingMessage, setEditingMessage] =
|
|
1034
|
-
const [editContent, setEditContent] =
|
|
1035
|
-
const [messageMenu, setMessageMenu] =
|
|
1036
|
-
const [isDragging, setIsDragging] =
|
|
1037
|
-
const [hoveredMessageId, setHoveredMessageId] =
|
|
1038
|
-
const [longPressTimer, setLongPressTimer] =
|
|
1039
|
-
const [
|
|
1040
|
-
const
|
|
1041
|
-
const
|
|
1042
|
-
const
|
|
1043
|
-
const
|
|
1044
|
-
|
|
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(() => {
|
|
1045
1838
|
const unsubOpen = client2.on("openChange", setIsOpen);
|
|
1046
1839
|
const unsubMessage = client2.on("message", () => {
|
|
1047
1840
|
setMessages([...client2.getMessages()]);
|
|
@@ -1057,6 +1850,10 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1057
1850
|
setMessages(client2.getMessages());
|
|
1058
1851
|
setOperatorOnline(client2.getSession()?.operatorOnline ?? false);
|
|
1059
1852
|
setConfig(client2.getConfig());
|
|
1853
|
+
setPreChatForm(client2.getSession()?.preChatForm);
|
|
1854
|
+
});
|
|
1855
|
+
const unsubPreChat = client2.on("preChatCompleted", () => {
|
|
1856
|
+
setPreChatForm((prev) => prev ? { ...prev, completed: true } : prev);
|
|
1060
1857
|
});
|
|
1061
1858
|
const unsubConfig = client2.on("configUpdate", () => {
|
|
1062
1859
|
setConfig(client2.getConfig());
|
|
@@ -1066,6 +1863,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1066
1863
|
setMessages(client2.getMessages());
|
|
1067
1864
|
setOperatorOnline(client2.getSession()?.operatorOnline ?? false);
|
|
1068
1865
|
setConfig(client2.getConfig());
|
|
1866
|
+
setPreChatForm(client2.getSession()?.preChatForm);
|
|
1069
1867
|
}
|
|
1070
1868
|
return () => {
|
|
1071
1869
|
unsubOpen();
|
|
@@ -1073,15 +1871,16 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1073
1871
|
unsubTyping();
|
|
1074
1872
|
unsubPresence();
|
|
1075
1873
|
unsubConnect();
|
|
1874
|
+
unsubPreChat();
|
|
1076
1875
|
unsubConfig();
|
|
1077
1876
|
};
|
|
1078
1877
|
}, [client2]);
|
|
1079
|
-
|
|
1878
|
+
useEffect2(() => {
|
|
1080
1879
|
if (isOpen) {
|
|
1081
1880
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
1082
1881
|
}
|
|
1083
1882
|
}, [messages, isOpen]);
|
|
1084
|
-
|
|
1883
|
+
useEffect2(() => {
|
|
1085
1884
|
if (isOpen) {
|
|
1086
1885
|
setTimeout(() => {
|
|
1087
1886
|
messagesEndRef.current?.scrollIntoView({ behavior: "auto" });
|
|
@@ -1090,7 +1889,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1090
1889
|
setUnreadCount(0);
|
|
1091
1890
|
}
|
|
1092
1891
|
}, [isOpen]);
|
|
1093
|
-
|
|
1892
|
+
useEffect2(() => {
|
|
1094
1893
|
if (!isOpen && messages.length > 0) {
|
|
1095
1894
|
const unread = messages.filter(
|
|
1096
1895
|
(msg) => msg.sender !== "visitor" && msg.status !== "read"
|
|
@@ -1108,14 +1907,14 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1108
1907
|
client2.sendReadStatus(messageIds, "read");
|
|
1109
1908
|
}
|
|
1110
1909
|
}, [isOpen, isConnected, messages, client2]);
|
|
1111
|
-
|
|
1910
|
+
useEffect2(() => {
|
|
1112
1911
|
if (!isOpen || !isConnected) return;
|
|
1113
1912
|
const timer = setTimeout(() => {
|
|
1114
1913
|
markMessagesAsRead();
|
|
1115
1914
|
}, 1e3);
|
|
1116
1915
|
return () => clearTimeout(timer);
|
|
1117
1916
|
}, [isOpen, isConnected, messages, markMessagesAsRead]);
|
|
1118
|
-
|
|
1917
|
+
useEffect2(() => {
|
|
1119
1918
|
const handleVisibilityChange = () => {
|
|
1120
1919
|
if (document.visibilityState === "visible" && isOpen) {
|
|
1121
1920
|
markMessagesAsRead();
|
|
@@ -1124,7 +1923,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1124
1923
|
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
1125
1924
|
return () => document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
1126
1925
|
}, [isOpen, markMessagesAsRead]);
|
|
1127
|
-
|
|
1926
|
+
useEffect2(() => {
|
|
1128
1927
|
const unsubRead = client2.on(
|
|
1129
1928
|
"read",
|
|
1130
1929
|
() => {
|
|
@@ -1263,26 +2062,43 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1263
2062
|
y: mouseEvent.clientY
|
|
1264
2063
|
});
|
|
1265
2064
|
};
|
|
1266
|
-
const handleTouchStart = (message) => {
|
|
1267
|
-
const
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
y: window.innerHeight / 2 - 50
|
|
1274
|
-
// Center vertically
|
|
1275
|
-
});
|
|
1276
|
-
}, 500);
|
|
1277
|
-
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
|
+
}
|
|
1278
2072
|
};
|
|
1279
|
-
const
|
|
1280
|
-
if (
|
|
1281
|
-
|
|
1282
|
-
|
|
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);
|
|
1283
2083
|
}
|
|
1284
2084
|
};
|
|
1285
|
-
|
|
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(() => {
|
|
1286
2102
|
if (!messageMenu) return;
|
|
1287
2103
|
const handleClickOutside = () => setMessageMenu(null);
|
|
1288
2104
|
document.addEventListener("click", handleClickOutside);
|
|
@@ -1298,7 +2114,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1298
2114
|
}, 1500);
|
|
1299
2115
|
}
|
|
1300
2116
|
};
|
|
1301
|
-
const dragCounterRef =
|
|
2117
|
+
const dragCounterRef = useRef2(0);
|
|
1302
2118
|
const handleDragEnter = (e) => {
|
|
1303
2119
|
e.preventDefault();
|
|
1304
2120
|
e.stopPropagation();
|
|
@@ -1374,22 +2190,24 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1374
2190
|
const theme = getTheme(config.theme ?? "auto");
|
|
1375
2191
|
const primaryColor = config.primaryColor ?? "#6366f1";
|
|
1376
2192
|
const actionIconColor = theme === "dark" ? "#9ca3af" : "#6b7280";
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
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(
|
|
1380
2198
|
"button",
|
|
1381
2199
|
{
|
|
1382
2200
|
class: `pp-toggle pp-${position}`,
|
|
1383
2201
|
onClick: () => client2.toggleOpen(),
|
|
1384
2202
|
"aria-label": isOpen ? "Close chat" : "Open chat",
|
|
1385
2203
|
children: [
|
|
1386
|
-
isOpen ? /* @__PURE__ */
|
|
1387
|
-
!isOpen && unreadCount > 0 && /* @__PURE__ */
|
|
1388
|
-
!isOpen && unreadCount === 0 && operatorOnline && /* @__PURE__ */
|
|
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" })
|
|
1389
2207
|
]
|
|
1390
2208
|
}
|
|
1391
2209
|
),
|
|
1392
|
-
isOpen && /* @__PURE__ */
|
|
2210
|
+
isOpen && /* @__PURE__ */ jsxs2(
|
|
1393
2211
|
"div",
|
|
1394
2212
|
{
|
|
1395
2213
|
class: `pp-window pp-${position} pp-theme-${theme} ${isDragging ? "pp-dragging" : ""}`,
|
|
@@ -1398,39 +2216,55 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1398
2216
|
onDragLeave: handleDragLeave,
|
|
1399
2217
|
onDrop: handleDrop,
|
|
1400
2218
|
children: [
|
|
1401
|
-
isDragging && /* @__PURE__ */
|
|
1402
|
-
/* @__PURE__ */
|
|
1403
|
-
/* @__PURE__ */
|
|
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" })
|
|
1404
2222
|
] }),
|
|
1405
|
-
/* @__PURE__ */
|
|
1406
|
-
/* @__PURE__ */
|
|
1407
|
-
config.operatorAvatar && /* @__PURE__ */
|
|
1408
|
-
/* @__PURE__ */
|
|
1409
|
-
/* @__PURE__ */
|
|
1410
|
-
/* @__PURE__ */
|
|
1411
|
-
/* @__PURE__ */
|
|
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" }),
|
|
1412
2230
|
" Online"
|
|
1413
|
-
] }) : /* @__PURE__ */
|
|
1414
|
-
/* @__PURE__ */
|
|
2231
|
+
] }) : /* @__PURE__ */ jsxs2(Fragment3, { children: [
|
|
2232
|
+
/* @__PURE__ */ jsx2("span", { class: "pp-status-dot" }),
|
|
1415
2233
|
" Away"
|
|
1416
2234
|
] }) })
|
|
1417
2235
|
] })
|
|
1418
2236
|
] }),
|
|
1419
|
-
/* @__PURE__ */
|
|
2237
|
+
/* @__PURE__ */ jsx2(
|
|
1420
2238
|
"button",
|
|
1421
2239
|
{
|
|
1422
2240
|
class: "pp-close-btn",
|
|
1423
2241
|
onClick: () => client2.setOpen(false),
|
|
1424
2242
|
"aria-label": "Close chat",
|
|
1425
|
-
children: /* @__PURE__ */
|
|
2243
|
+
children: /* @__PURE__ */ jsx2(CloseIcon, {})
|
|
1426
2244
|
}
|
|
1427
2245
|
)
|
|
1428
2246
|
] }),
|
|
1429
|
-
/* @__PURE__ */
|
|
1430
|
-
|
|
1431
|
-
|
|
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 }),
|
|
2262
|
+
messages.map((msg, index) => {
|
|
1432
2263
|
const isDeleted = !!msg.deletedAt;
|
|
1433
2264
|
const isEdited = !!msg.editedAt;
|
|
2265
|
+
const msgDate = new Date(msg.timestamp);
|
|
2266
|
+
const prevMsg = index > 0 ? messages[index - 1] : null;
|
|
2267
|
+
const showDateSeparator = !prevMsg || getDateKey(new Date(prevMsg.timestamp)) !== getDateKey(msgDate);
|
|
1434
2268
|
let replyData = null;
|
|
1435
2269
|
if (msg.replyTo) {
|
|
1436
2270
|
if (typeof msg.replyTo === "object") {
|
|
@@ -1452,123 +2286,168 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1452
2286
|
}
|
|
1453
2287
|
const isHovered = hoveredMessageId === msg.id;
|
|
1454
2288
|
const showActions = isHovered && !isDeleted;
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
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(
|
|
1469
2308
|
"button",
|
|
1470
2309
|
{
|
|
1471
|
-
class: "pp-action-
|
|
1472
|
-
onClick: () =>
|
|
1473
|
-
|
|
1474
|
-
|
|
2310
|
+
class: "pp-swipe-action pp-swipe-edit",
|
|
2311
|
+
onClick: () => {
|
|
2312
|
+
handleStartEdit(msg);
|
|
2313
|
+
resetSwipe();
|
|
2314
|
+
},
|
|
2315
|
+
children: /* @__PURE__ */ jsx2(EditIcon, { color: "#fff" })
|
|
1475
2316
|
}
|
|
1476
2317
|
),
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
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(
|
|
2347
|
+
"button",
|
|
2348
|
+
{
|
|
2349
|
+
class: "pp-action-btn",
|
|
2350
|
+
onClick: () => handleReply(msg),
|
|
2351
|
+
title: "Reply",
|
|
2352
|
+
children: /* @__PURE__ */ jsx2(ReplyIcon, { color: actionIconColor })
|
|
2353
|
+
}
|
|
2354
|
+
),
|
|
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",
|
|
1480
2378
|
{
|
|
1481
|
-
class: "pp-
|
|
1482
|
-
onClick: () =>
|
|
1483
|
-
|
|
1484
|
-
|
|
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
|
+
]
|
|
1485
2394
|
}
|
|
1486
2395
|
),
|
|
1487
|
-
/* @__PURE__ */
|
|
1488
|
-
"
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
onKeyDown: (e) => e.key === "Enter" && scrollToMessage(replyData.id),
|
|
1506
|
-
children: [
|
|
1507
|
-
/* @__PURE__ */ jsx("span", { class: "pp-reply-sender", children: replyData.sender === "visitor" ? "You" : "Support" }),
|
|
1508
|
-
/* @__PURE__ */ jsx("span", { class: "pp-reply-content", children: replyData.deleted ? "Message deleted" : /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
1509
|
-
replyData.hasAttachment && /* @__PURE__ */ jsx("span", { class: "pp-reply-attachment-icon", children: replyData.attachmentType?.startsWith("image/") ? "\u{1F4F7} " : "\u{1F4CE} " }),
|
|
1510
|
-
replyData.content ? /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
1511
|
-
(replyData.content || "").slice(0, 50),
|
|
1512
|
-
(replyData.content || "").length > 50 ? "..." : ""
|
|
1513
|
-
] }) : replyData.attachmentType?.startsWith("image/") ? "Photo" : "File"
|
|
1514
|
-
] }) })
|
|
1515
|
-
]
|
|
1516
|
-
}
|
|
1517
|
-
),
|
|
1518
|
-
isDeleted ? /* @__PURE__ */ jsxs("div", { class: "pp-message-content pp-deleted-content", children: [
|
|
1519
|
-
/* @__PURE__ */ jsx("span", { class: "pp-deleted-icon", children: "\u{1F5D1}\uFE0F" }),
|
|
1520
|
-
" Message deleted"
|
|
1521
|
-
] }) : /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
1522
|
-
msg.content && /* @__PURE__ */ jsx("div", { class: "pp-message-content", children: msg.content }),
|
|
1523
|
-
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)) })
|
|
1524
|
-
] }),
|
|
1525
|
-
/* @__PURE__ */ jsxs("div", { class: "pp-message-time", children: [
|
|
1526
|
-
formatTime(msg.timestamp),
|
|
1527
|
-
isEdited && !isDeleted && /* @__PURE__ */ jsx("span", { class: "pp-edited-badge", children: "edited" }),
|
|
1528
|
-
msg.sender === "ai" && /* @__PURE__ */ jsx("span", { class: "pp-ai-badge", children: "AI" }),
|
|
1529
|
-
msg.sender === "visitor" && !isDeleted && /* @__PURE__ */ jsx("span", { class: `pp-status pp-status-${msg.status ?? "sent"}`, children: /* @__PURE__ */ jsx(StatusIcon, { status: msg.status }) })
|
|
1530
|
-
] })
|
|
1531
|
-
]
|
|
1532
|
-
},
|
|
1533
|
-
msg.id
|
|
1534
|
-
);
|
|
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 }) })
|
|
2408
|
+
] })
|
|
2409
|
+
]
|
|
2410
|
+
}
|
|
2411
|
+
)
|
|
2412
|
+
] })
|
|
2413
|
+
] }, msg.id);
|
|
1535
2414
|
}),
|
|
1536
|
-
isTyping && /* @__PURE__ */
|
|
1537
|
-
/* @__PURE__ */
|
|
1538
|
-
/* @__PURE__ */
|
|
1539
|
-
/* @__PURE__ */
|
|
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", {})
|
|
1540
2419
|
] }),
|
|
1541
|
-
/* @__PURE__ */
|
|
2420
|
+
/* @__PURE__ */ jsx2("div", { ref: messagesEndRef })
|
|
1542
2421
|
] }),
|
|
1543
|
-
messageMenu && /* @__PURE__ */
|
|
2422
|
+
messageMenu && /* @__PURE__ */ jsxs2(
|
|
1544
2423
|
"div",
|
|
1545
2424
|
{
|
|
1546
2425
|
class: "pp-message-menu",
|
|
1547
2426
|
style: { top: `${messageMenu.y}px`, left: `${messageMenu.x}px` },
|
|
1548
2427
|
children: [
|
|
1549
|
-
/* @__PURE__ */
|
|
1550
|
-
/* @__PURE__ */
|
|
2428
|
+
/* @__PURE__ */ jsxs2("button", { onClick: () => handleReply(messageMenu.message), children: [
|
|
2429
|
+
/* @__PURE__ */ jsx2(ReplyIcon, { color: actionIconColor }),
|
|
1551
2430
|
" Reply"
|
|
1552
2431
|
] }),
|
|
1553
|
-
messageMenu.message.sender === "visitor" && !messageMenu.message.deletedAt && /* @__PURE__ */
|
|
1554
|
-
/* @__PURE__ */
|
|
1555
|
-
/* @__PURE__ */
|
|
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 }),
|
|
1556
2435
|
" Edit"
|
|
1557
2436
|
] }),
|
|
1558
|
-
/* @__PURE__ */
|
|
1559
|
-
/* @__PURE__ */
|
|
2437
|
+
/* @__PURE__ */ jsxs2("button", { class: "pp-menu-delete", onClick: () => handleDelete(messageMenu.message), children: [
|
|
2438
|
+
/* @__PURE__ */ jsx2(DeleteIcon, { color: "#ef4444" }),
|
|
1560
2439
|
" Delete"
|
|
1561
2440
|
] })
|
|
1562
2441
|
] })
|
|
1563
2442
|
]
|
|
1564
2443
|
}
|
|
1565
2444
|
),
|
|
1566
|
-
editingMessage && /* @__PURE__ */
|
|
1567
|
-
/* @__PURE__ */
|
|
1568
|
-
/* @__PURE__ */
|
|
1569
|
-
/* @__PURE__ */
|
|
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, {}) })
|
|
1570
2449
|
] }),
|
|
1571
|
-
/* @__PURE__ */
|
|
2450
|
+
/* @__PURE__ */ jsx2(
|
|
1572
2451
|
"textarea",
|
|
1573
2452
|
{
|
|
1574
2453
|
class: "pp-edit-input",
|
|
@@ -1577,41 +2456,41 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1577
2456
|
autoFocus: true
|
|
1578
2457
|
}
|
|
1579
2458
|
),
|
|
1580
|
-
/* @__PURE__ */
|
|
1581
|
-
/* @__PURE__ */
|
|
1582
|
-
/* @__PURE__ */
|
|
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" })
|
|
1583
2462
|
] })
|
|
1584
2463
|
] }),
|
|
1585
|
-
replyingTo && /* @__PURE__ */
|
|
1586
|
-
/* @__PURE__ */
|
|
1587
|
-
/* @__PURE__ */
|
|
1588
|
-
/* @__PURE__ */
|
|
1589
|
-
replyingTo.attachments && replyingTo.attachments.length > 0 && /* @__PURE__ */
|
|
1590
|
-
replyingTo.content ? /* @__PURE__ */
|
|
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: [
|
|
1591
2470
|
replyingTo.content.slice(0, 50),
|
|
1592
2471
|
replyingTo.content.length > 50 ? "..." : ""
|
|
1593
2472
|
] }) : replyingTo.attachments?.[0]?.mimeType.startsWith("image/") ? "Photo" : "File"
|
|
1594
2473
|
] })
|
|
1595
2474
|
] }),
|
|
1596
|
-
/* @__PURE__ */
|
|
2475
|
+
/* @__PURE__ */ jsx2("button", { class: "pp-reply-cancel", onClick: handleCancelReply, children: /* @__PURE__ */ jsx2(CloseIcon, {}) })
|
|
1597
2476
|
] }),
|
|
1598
|
-
pendingAttachments.length > 0 && /* @__PURE__ */
|
|
1599
|
-
pending.preview ? /* @__PURE__ */
|
|
1600
|
-
/* @__PURE__ */
|
|
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(
|
|
1601
2480
|
"button",
|
|
1602
2481
|
{
|
|
1603
2482
|
class: "pp-remove-attachment",
|
|
1604
2483
|
onClick: () => handleRemoveAttachment(pending.id),
|
|
1605
2484
|
"aria-label": "Remove attachment",
|
|
1606
2485
|
type: "button",
|
|
1607
|
-
children: /* @__PURE__ */
|
|
2486
|
+
children: /* @__PURE__ */ jsx2(CloseIcon, {})
|
|
1608
2487
|
}
|
|
1609
2488
|
),
|
|
1610
|
-
pending.status === "uploading" && /* @__PURE__ */
|
|
1611
|
-
pending.status === "error" && /* @__PURE__ */
|
|
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: "!" })
|
|
1612
2491
|
] }, pending.id)) }),
|
|
1613
|
-
/* @__PURE__ */
|
|
1614
|
-
/* @__PURE__ */
|
|
2492
|
+
!shouldShowPreChat && /* @__PURE__ */ jsxs2("form", { class: "pp-input-form", onSubmit: handleSubmit, children: [
|
|
2493
|
+
/* @__PURE__ */ jsx2(
|
|
1615
2494
|
"input",
|
|
1616
2495
|
{
|
|
1617
2496
|
ref: (el) => {
|
|
@@ -1626,7 +2505,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1626
2505
|
multiple: true
|
|
1627
2506
|
}
|
|
1628
2507
|
),
|
|
1629
|
-
/* @__PURE__ */
|
|
2508
|
+
/* @__PURE__ */ jsx2(
|
|
1630
2509
|
"button",
|
|
1631
2510
|
{
|
|
1632
2511
|
type: "button",
|
|
@@ -1634,10 +2513,10 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1634
2513
|
onClick: () => fileInputRef.current?.click(),
|
|
1635
2514
|
disabled: !isConnected || isUploading,
|
|
1636
2515
|
"aria-label": "Attach file",
|
|
1637
|
-
children: /* @__PURE__ */
|
|
2516
|
+
children: /* @__PURE__ */ jsx2(AttachIcon, {})
|
|
1638
2517
|
}
|
|
1639
2518
|
),
|
|
1640
|
-
/* @__PURE__ */
|
|
2519
|
+
/* @__PURE__ */ jsx2(
|
|
1641
2520
|
"input",
|
|
1642
2521
|
{
|
|
1643
2522
|
ref: inputRef,
|
|
@@ -1649,20 +2528,20 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1649
2528
|
disabled: !isConnected
|
|
1650
2529
|
}
|
|
1651
2530
|
),
|
|
1652
|
-
/* @__PURE__ */
|
|
2531
|
+
/* @__PURE__ */ jsx2(
|
|
1653
2532
|
"button",
|
|
1654
2533
|
{
|
|
1655
2534
|
type: "submit",
|
|
1656
2535
|
class: "pp-send-btn",
|
|
1657
2536
|
disabled: !inputValue.trim() && pendingAttachments.filter((a) => a.status === "ready").length === 0 || !isConnected || isUploading,
|
|
1658
2537
|
"aria-label": "Send message",
|
|
1659
|
-
children: /* @__PURE__ */
|
|
2538
|
+
children: /* @__PURE__ */ jsx2(SendIcon, {})
|
|
1660
2539
|
}
|
|
1661
2540
|
)
|
|
1662
2541
|
] }),
|
|
1663
|
-
/* @__PURE__ */
|
|
2542
|
+
/* @__PURE__ */ jsxs2("div", { class: "pp-footer", children: [
|
|
1664
2543
|
"Powered by ",
|
|
1665
|
-
/* @__PURE__ */
|
|
2544
|
+
/* @__PURE__ */ jsx2("a", { href: "https://pocketping.io", target: "_blank", rel: "noopener", children: "PocketPing" })
|
|
1666
2545
|
] })
|
|
1667
2546
|
]
|
|
1668
2547
|
}
|
|
@@ -1690,90 +2569,90 @@ function formatTime(timestamp) {
|
|
|
1690
2569
|
return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
1691
2570
|
}
|
|
1692
2571
|
function ChatIcon() {
|
|
1693
|
-
return /* @__PURE__ */
|
|
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" }) });
|
|
1694
2573
|
}
|
|
1695
2574
|
function CloseIcon() {
|
|
1696
|
-
return /* @__PURE__ */
|
|
1697
|
-
/* @__PURE__ */
|
|
1698
|
-
/* @__PURE__ */
|
|
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" })
|
|
1699
2578
|
] });
|
|
1700
2579
|
}
|
|
1701
2580
|
function SendIcon() {
|
|
1702
|
-
return /* @__PURE__ */
|
|
1703
|
-
/* @__PURE__ */
|
|
1704
|
-
/* @__PURE__ */
|
|
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" })
|
|
1705
2584
|
] });
|
|
1706
2585
|
}
|
|
1707
2586
|
function StatusIcon({ status }) {
|
|
1708
2587
|
if (!status || status === "sending" || status === "sent") {
|
|
1709
|
-
return /* @__PURE__ */
|
|
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" }) });
|
|
1710
2589
|
}
|
|
1711
2590
|
if (status === "delivered") {
|
|
1712
|
-
return /* @__PURE__ */
|
|
1713
|
-
/* @__PURE__ */
|
|
1714
|
-
/* @__PURE__ */
|
|
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" })
|
|
1715
2594
|
] });
|
|
1716
2595
|
}
|
|
1717
2596
|
if (status === "read") {
|
|
1718
|
-
return /* @__PURE__ */
|
|
1719
|
-
/* @__PURE__ */
|
|
1720
|
-
/* @__PURE__ */
|
|
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" })
|
|
1721
2600
|
] });
|
|
1722
2601
|
}
|
|
1723
2602
|
return null;
|
|
1724
2603
|
}
|
|
1725
2604
|
function AttachIcon() {
|
|
1726
|
-
return /* @__PURE__ */
|
|
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" }) });
|
|
1727
2606
|
}
|
|
1728
2607
|
function ReplyIcon({ color, size = 16 }) {
|
|
1729
2608
|
const strokeColor = color || "currentColor";
|
|
1730
|
-
return /* @__PURE__ */
|
|
1731
|
-
/* @__PURE__ */
|
|
1732
|
-
/* @__PURE__ */
|
|
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" })
|
|
1733
2612
|
] });
|
|
1734
2613
|
}
|
|
1735
2614
|
function EditIcon({ color, size = 16 }) {
|
|
1736
2615
|
const strokeColor = color || "currentColor";
|
|
1737
|
-
return /* @__PURE__ */
|
|
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" }) });
|
|
1738
2617
|
}
|
|
1739
2618
|
function DeleteIcon({ color, size = 16 }) {
|
|
1740
2619
|
const strokeColor = color || "currentColor";
|
|
1741
|
-
return /* @__PURE__ */
|
|
1742
|
-
/* @__PURE__ */
|
|
1743
|
-
/* @__PURE__ */
|
|
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" })
|
|
1744
2623
|
] });
|
|
1745
2624
|
}
|
|
1746
2625
|
function FileIcon({ mimeType }) {
|
|
1747
2626
|
if (mimeType === "application/pdf") {
|
|
1748
|
-
return /* @__PURE__ */
|
|
1749
|
-
/* @__PURE__ */
|
|
1750
|
-
/* @__PURE__ */
|
|
1751
|
-
/* @__PURE__ */
|
|
1752
|
-
/* @__PURE__ */
|
|
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" })
|
|
1753
2632
|
] });
|
|
1754
2633
|
}
|
|
1755
2634
|
if (mimeType.startsWith("audio/")) {
|
|
1756
|
-
return /* @__PURE__ */
|
|
1757
|
-
/* @__PURE__ */
|
|
1758
|
-
/* @__PURE__ */
|
|
1759
|
-
/* @__PURE__ */
|
|
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" })
|
|
1760
2639
|
] });
|
|
1761
2640
|
}
|
|
1762
2641
|
if (mimeType.startsWith("video/")) {
|
|
1763
|
-
return /* @__PURE__ */
|
|
1764
|
-
/* @__PURE__ */
|
|
1765
|
-
/* @__PURE__ */
|
|
1766
|
-
/* @__PURE__ */
|
|
1767
|
-
/* @__PURE__ */
|
|
1768
|
-
/* @__PURE__ */
|
|
1769
|
-
/* @__PURE__ */
|
|
1770
|
-
/* @__PURE__ */
|
|
1771
|
-
/* @__PURE__ */
|
|
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" })
|
|
1772
2651
|
] });
|
|
1773
2652
|
}
|
|
1774
|
-
return /* @__PURE__ */
|
|
1775
|
-
/* @__PURE__ */
|
|
1776
|
-
/* @__PURE__ */
|
|
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" })
|
|
1777
2656
|
] });
|
|
1778
2657
|
}
|
|
1779
2658
|
function AttachmentDisplay({ attachment }) {
|
|
@@ -1786,28 +2665,28 @@ function AttachmentDisplay({ attachment }) {
|
|
|
1786
2665
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1787
2666
|
};
|
|
1788
2667
|
if (isImage) {
|
|
1789
|
-
return /* @__PURE__ */
|
|
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 }) });
|
|
1790
2669
|
}
|
|
1791
2670
|
if (isAudio) {
|
|
1792
|
-
return /* @__PURE__ */
|
|
1793
|
-
/* @__PURE__ */
|
|
1794
|
-
/* @__PURE__ */
|
|
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 })
|
|
1795
2674
|
] });
|
|
1796
2675
|
}
|
|
1797
2676
|
if (isVideo) {
|
|
1798
|
-
return /* @__PURE__ */
|
|
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 }) }) });
|
|
1799
2678
|
}
|
|
1800
|
-
return /* @__PURE__ */
|
|
1801
|
-
/* @__PURE__ */
|
|
1802
|
-
/* @__PURE__ */
|
|
1803
|
-
/* @__PURE__ */
|
|
1804
|
-
/* @__PURE__ */
|
|
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) })
|
|
1805
2684
|
] })
|
|
1806
2685
|
] });
|
|
1807
2686
|
}
|
|
1808
2687
|
|
|
1809
2688
|
// src/version.ts
|
|
1810
|
-
var VERSION = "0.3.
|
|
2689
|
+
var VERSION = "0.3.7";
|
|
1811
2690
|
|
|
1812
2691
|
// src/client.ts
|
|
1813
2692
|
var PocketPingClient = class {
|
|
@@ -1867,7 +2746,8 @@ var PocketPingClient = class {
|
|
|
1867
2746
|
visitorId: response.visitorId,
|
|
1868
2747
|
operatorOnline: response.operatorOnline ?? false,
|
|
1869
2748
|
messages: response.messages ?? [],
|
|
1870
|
-
identity: response.identity || storedIdentity || void 0
|
|
2749
|
+
identity: response.identity || storedIdentity || void 0,
|
|
2750
|
+
preChatForm: response.preChatForm
|
|
1871
2751
|
};
|
|
1872
2752
|
if (response.operatorName) {
|
|
1873
2753
|
this.config.operatorName = response.operatorName;
|
|
@@ -2223,6 +3103,36 @@ var PocketPingClient = class {
|
|
|
2223
3103
|
}
|
|
2224
3104
|
}
|
|
2225
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
|
+
}
|
|
2226
3136
|
/**
|
|
2227
3137
|
* Reset the user identity and optionally start a new session
|
|
2228
3138
|
* Call on user logout to clear user data
|
|
@@ -2872,6 +3782,12 @@ var PocketPingClient = class {
|
|
|
2872
3782
|
this.session.messages.push(message);
|
|
2873
3783
|
this.emit("message", message);
|
|
2874
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
|
+
}
|
|
2875
3791
|
}
|
|
2876
3792
|
}
|
|
2877
3793
|
if (message.sender !== "visitor") {
|
|
@@ -3030,6 +3946,12 @@ var PocketPingClient = class {
|
|
|
3030
3946
|
this.session.messages.push(message);
|
|
3031
3947
|
this.emit("message", message);
|
|
3032
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
|
+
}
|
|
3033
3955
|
}
|
|
3034
3956
|
}
|
|
3035
3957
|
} catch (err) {
|