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