@pocketping/widget 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +306 -23
- package/dist/index.d.cts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +306 -23
- package/dist/pocketping.min.global.js +108 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -228,6 +228,94 @@ function styles(primaryColor, theme) {
|
|
|
228
228
|
padding: 10px 14px;
|
|
229
229
|
border-radius: 16px;
|
|
230
230
|
word-wrap: break-word;
|
|
231
|
+
position: relative;
|
|
232
|
+
user-select: text;
|
|
233
|
+
-webkit-user-select: text;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* Hover actions container - positioned above message (Slack style) */
|
|
237
|
+
.pp-message-actions {
|
|
238
|
+
position: absolute;
|
|
239
|
+
top: -28px;
|
|
240
|
+
display: flex;
|
|
241
|
+
gap: 2px;
|
|
242
|
+
background: ${colors.bg};
|
|
243
|
+
border: 1px solid ${colors.border};
|
|
244
|
+
border-radius: 6px;
|
|
245
|
+
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
|
|
246
|
+
padding: 2px;
|
|
247
|
+
opacity: 0;
|
|
248
|
+
animation: pp-actions-fade-in 0.12s ease forwards;
|
|
249
|
+
z-index: 10;
|
|
250
|
+
/* Reset color inheritance from message */
|
|
251
|
+
color: ${colors.textSecondary};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
@keyframes pp-actions-fade-in {
|
|
255
|
+
from { opacity: 0; transform: translateY(4px); }
|
|
256
|
+
to { opacity: 1; transform: translateY(0); }
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/* Visitor messages: actions aligned right */
|
|
260
|
+
.pp-actions-left {
|
|
261
|
+
right: 0;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/* Operator messages: actions aligned left */
|
|
265
|
+
.pp-actions-right {
|
|
266
|
+
left: 0;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.pp-message-actions .pp-action-btn {
|
|
270
|
+
width: 24px;
|
|
271
|
+
height: 24px;
|
|
272
|
+
border: none;
|
|
273
|
+
background: transparent;
|
|
274
|
+
border-radius: 4px;
|
|
275
|
+
cursor: pointer;
|
|
276
|
+
display: flex;
|
|
277
|
+
align-items: center;
|
|
278
|
+
justify-content: center;
|
|
279
|
+
color: ${colors.textSecondary} !important;
|
|
280
|
+
transition: background 0.1s, color 0.1s;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.pp-message-actions .pp-action-btn:hover {
|
|
284
|
+
background: ${colors.bgSecondary};
|
|
285
|
+
color: ${colors.text} !important;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.pp-message-actions .pp-action-btn svg {
|
|
289
|
+
width: 14px;
|
|
290
|
+
height: 14px;
|
|
291
|
+
stroke: ${colors.textSecondary};
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.pp-message-actions .pp-action-btn:hover svg {
|
|
295
|
+
stroke: ${colors.text};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.pp-message-actions .pp-action-delete:hover {
|
|
299
|
+
background: #fef2f2;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.pp-message-actions .pp-action-delete:hover svg {
|
|
303
|
+
stroke: #ef4444;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.pp-theme-dark .pp-message-actions .pp-action-delete:hover {
|
|
307
|
+
background: #7f1d1d;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.pp-theme-dark .pp-message-actions .pp-action-delete:hover svg {
|
|
311
|
+
stroke: #fca5a5;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/* Hide hover actions on mobile */
|
|
315
|
+
@media (hover: none) and (pointer: coarse) {
|
|
316
|
+
.pp-message-actions {
|
|
317
|
+
display: none;
|
|
318
|
+
}
|
|
231
319
|
}
|
|
232
320
|
|
|
233
321
|
.pp-message-visitor {
|
|
@@ -609,9 +697,8 @@ function styles(primaryColor, theme) {
|
|
|
609
697
|
}
|
|
610
698
|
|
|
611
699
|
/* Drag & Drop */
|
|
612
|
-
.pp-
|
|
613
|
-
|
|
614
|
-
}
|
|
700
|
+
/* Note: .pp-window already has position: fixed which acts as
|
|
701
|
+
containing block for the absolutely positioned overlay */
|
|
615
702
|
|
|
616
703
|
.pp-drop-overlay {
|
|
617
704
|
position: absolute;
|
|
@@ -817,6 +904,8 @@ function styles(primaryColor, theme) {
|
|
|
817
904
|
margin-bottom: 6px;
|
|
818
905
|
border-radius: 0 4px 4px 0;
|
|
819
906
|
font-size: 12px;
|
|
907
|
+
position: relative;
|
|
908
|
+
z-index: 1;
|
|
820
909
|
}
|
|
821
910
|
|
|
822
911
|
.pp-reply-sender {
|
|
@@ -834,6 +923,17 @@ function styles(primaryColor, theme) {
|
|
|
834
923
|
text-overflow: ellipsis;
|
|
835
924
|
}
|
|
836
925
|
|
|
926
|
+
/* Reply quote in visitor message bubble needs higher contrast */
|
|
927
|
+
.pp-message-visitor .pp-reply-quote {
|
|
928
|
+
background: rgba(255, 255, 255, 0.18);
|
|
929
|
+
border-left-color: rgba(255, 255, 255, 0.7);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
.pp-message-visitor .pp-reply-sender,
|
|
933
|
+
.pp-message-visitor .pp-reply-content {
|
|
934
|
+
color: rgba(255, 255, 255, 0.9);
|
|
935
|
+
}
|
|
936
|
+
|
|
837
937
|
/* Deleted Message */
|
|
838
938
|
.pp-message-deleted {
|
|
839
939
|
opacity: 0.6;
|
|
@@ -878,6 +978,8 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
878
978
|
const [editContent, setEditContent] = useState("");
|
|
879
979
|
const [messageMenu, setMessageMenu] = useState(null);
|
|
880
980
|
const [isDragging, setIsDragging] = useState(false);
|
|
981
|
+
const [hoveredMessageId, setHoveredMessageId] = useState(null);
|
|
982
|
+
const [longPressTimer, setLongPressTimer] = useState(null);
|
|
881
983
|
const [config, setConfig] = useState(initialConfig);
|
|
882
984
|
const messagesEndRef = useRef(null);
|
|
883
985
|
const inputRef = useRef(null);
|
|
@@ -1105,6 +1207,25 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1105
1207
|
y: mouseEvent.clientY
|
|
1106
1208
|
});
|
|
1107
1209
|
};
|
|
1210
|
+
const handleTouchStart = (message) => {
|
|
1211
|
+
const timer = setTimeout(() => {
|
|
1212
|
+
if (navigator.vibrate) navigator.vibrate(50);
|
|
1213
|
+
setMessageMenu({
|
|
1214
|
+
message,
|
|
1215
|
+
x: window.innerWidth / 2 - 60,
|
|
1216
|
+
// Center horizontally
|
|
1217
|
+
y: window.innerHeight / 2 - 50
|
|
1218
|
+
// Center vertically
|
|
1219
|
+
});
|
|
1220
|
+
}, 500);
|
|
1221
|
+
setLongPressTimer(timer);
|
|
1222
|
+
};
|
|
1223
|
+
const handleTouchEnd = () => {
|
|
1224
|
+
if (longPressTimer) {
|
|
1225
|
+
clearTimeout(longPressTimer);
|
|
1226
|
+
setLongPressTimer(null);
|
|
1227
|
+
}
|
|
1228
|
+
};
|
|
1108
1229
|
useEffect(() => {
|
|
1109
1230
|
if (!messageMenu) return;
|
|
1110
1231
|
const handleClickOutside = () => setMessageMenu(null);
|
|
@@ -1186,6 +1307,7 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1186
1307
|
const position = config.position ?? "bottom-right";
|
|
1187
1308
|
const theme = getTheme(config.theme ?? "auto");
|
|
1188
1309
|
const primaryColor = config.primaryColor ?? "#6366f1";
|
|
1310
|
+
const actionIconColor = theme === "dark" ? "#9ca3af" : "#6b7280";
|
|
1189
1311
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1190
1312
|
/* @__PURE__ */ jsx("style", { children: styles(primaryColor, theme) }),
|
|
1191
1313
|
/* @__PURE__ */ jsxs(
|
|
@@ -1243,18 +1365,70 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1243
1365
|
messages.map((msg) => {
|
|
1244
1366
|
const isDeleted = !!msg.deletedAt;
|
|
1245
1367
|
const isEdited = !!msg.editedAt;
|
|
1246
|
-
|
|
1368
|
+
let replyData = null;
|
|
1369
|
+
if (msg.replyTo) {
|
|
1370
|
+
if (typeof msg.replyTo === "object") {
|
|
1371
|
+
replyData = msg.replyTo;
|
|
1372
|
+
} else {
|
|
1373
|
+
const replyToMsg = messages.find((m) => m.id === msg.replyTo);
|
|
1374
|
+
if (replyToMsg) {
|
|
1375
|
+
replyData = {
|
|
1376
|
+
sender: replyToMsg.sender,
|
|
1377
|
+
content: replyToMsg.content,
|
|
1378
|
+
deleted: !!replyToMsg.deletedAt
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
const isHovered = hoveredMessageId === msg.id;
|
|
1384
|
+
const showActions = isHovered && !isDeleted;
|
|
1247
1385
|
return /* @__PURE__ */ jsxs(
|
|
1248
1386
|
"div",
|
|
1249
1387
|
{
|
|
1250
1388
|
class: `pp-message pp-message-${msg.sender} ${isDeleted ? "pp-message-deleted" : ""}`,
|
|
1251
1389
|
onContextMenu: (e) => handleMessageContextMenu(e, msg),
|
|
1390
|
+
onMouseEnter: () => setHoveredMessageId(msg.id),
|
|
1391
|
+
onMouseLeave: () => setHoveredMessageId(null),
|
|
1392
|
+
onTouchStart: () => handleTouchStart(msg),
|
|
1393
|
+
onTouchEnd: handleTouchEnd,
|
|
1394
|
+
onTouchCancel: handleTouchEnd,
|
|
1252
1395
|
children: [
|
|
1253
|
-
|
|
1254
|
-
/* @__PURE__ */ jsx(
|
|
1396
|
+
showActions && /* @__PURE__ */ jsxs("div", { class: `pp-message-actions ${msg.sender === "visitor" ? "pp-actions-left" : "pp-actions-right"}`, children: [
|
|
1397
|
+
/* @__PURE__ */ jsx(
|
|
1398
|
+
"button",
|
|
1399
|
+
{
|
|
1400
|
+
class: "pp-action-btn",
|
|
1401
|
+
onClick: () => handleReply(msg),
|
|
1402
|
+
title: "Reply",
|
|
1403
|
+
children: /* @__PURE__ */ jsx(ReplyIcon, { color: actionIconColor })
|
|
1404
|
+
}
|
|
1405
|
+
),
|
|
1406
|
+
msg.sender === "visitor" && /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
1407
|
+
/* @__PURE__ */ jsx(
|
|
1408
|
+
"button",
|
|
1409
|
+
{
|
|
1410
|
+
class: "pp-action-btn",
|
|
1411
|
+
onClick: () => handleStartEdit(msg),
|
|
1412
|
+
title: "Edit",
|
|
1413
|
+
children: /* @__PURE__ */ jsx(EditIcon, { color: actionIconColor })
|
|
1414
|
+
}
|
|
1415
|
+
),
|
|
1416
|
+
/* @__PURE__ */ jsx(
|
|
1417
|
+
"button",
|
|
1418
|
+
{
|
|
1419
|
+
class: "pp-action-btn pp-action-delete",
|
|
1420
|
+
onClick: () => handleDelete(msg),
|
|
1421
|
+
title: "Delete",
|
|
1422
|
+
children: /* @__PURE__ */ jsx(DeleteIcon, { color: actionIconColor })
|
|
1423
|
+
}
|
|
1424
|
+
)
|
|
1425
|
+
] })
|
|
1426
|
+
] }),
|
|
1427
|
+
replyData && replyData.content && /* @__PURE__ */ jsxs("div", { class: "pp-reply-quote", children: [
|
|
1428
|
+
/* @__PURE__ */ jsx("span", { class: "pp-reply-sender", children: replyData.sender === "visitor" ? "You" : "Support" }),
|
|
1255
1429
|
/* @__PURE__ */ jsxs("span", { class: "pp-reply-content", children: [
|
|
1256
|
-
|
|
1257
|
-
|
|
1430
|
+
replyData.deleted ? "Message deleted" : (replyData.content || "").slice(0, 50),
|
|
1431
|
+
(replyData.content || "").length > 50 ? "..." : ""
|
|
1258
1432
|
] })
|
|
1259
1433
|
] }),
|
|
1260
1434
|
isDeleted ? /* @__PURE__ */ jsxs("div", { class: "pp-message-content pp-deleted-content", children: [
|
|
@@ -1289,16 +1463,16 @@ function ChatWidget({ client: client2, config: initialConfig }) {
|
|
|
1289
1463
|
style: { top: `${messageMenu.y}px`, left: `${messageMenu.x}px` },
|
|
1290
1464
|
children: [
|
|
1291
1465
|
/* @__PURE__ */ jsxs("button", { onClick: () => handleReply(messageMenu.message), children: [
|
|
1292
|
-
/* @__PURE__ */ jsx(ReplyIcon, {}),
|
|
1466
|
+
/* @__PURE__ */ jsx(ReplyIcon, { color: actionIconColor }),
|
|
1293
1467
|
" Reply"
|
|
1294
1468
|
] }),
|
|
1295
1469
|
messageMenu.message.sender === "visitor" && !messageMenu.message.deletedAt && /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
1296
1470
|
/* @__PURE__ */ jsxs("button", { onClick: () => handleStartEdit(messageMenu.message), children: [
|
|
1297
|
-
/* @__PURE__ */ jsx(EditIcon, {}),
|
|
1471
|
+
/* @__PURE__ */ jsx(EditIcon, { color: actionIconColor }),
|
|
1298
1472
|
" Edit"
|
|
1299
1473
|
] }),
|
|
1300
1474
|
/* @__PURE__ */ jsxs("button", { class: "pp-menu-delete", onClick: () => handleDelete(messageMenu.message), children: [
|
|
1301
|
-
/* @__PURE__ */ jsx(DeleteIcon, {}),
|
|
1475
|
+
/* @__PURE__ */ jsx(DeleteIcon, { color: "#ef4444" }),
|
|
1302
1476
|
" Delete"
|
|
1303
1477
|
] })
|
|
1304
1478
|
] })
|
|
@@ -1464,17 +1638,20 @@ function StatusIcon({ status }) {
|
|
|
1464
1638
|
function AttachIcon() {
|
|
1465
1639
|
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", children: /* @__PURE__ */ jsx("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
|
|
1466
1640
|
}
|
|
1467
|
-
function ReplyIcon() {
|
|
1468
|
-
|
|
1641
|
+
function ReplyIcon({ color, size = 16 }) {
|
|
1642
|
+
const strokeColor = color || "currentColor";
|
|
1643
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: [
|
|
1469
1644
|
/* @__PURE__ */ jsx("polyline", { points: "9 17 4 12 9 7" }),
|
|
1470
1645
|
/* @__PURE__ */ jsx("path", { d: "M20 18v-2a4 4 0 0 0-4-4H4" })
|
|
1471
1646
|
] });
|
|
1472
1647
|
}
|
|
1473
|
-
function EditIcon() {
|
|
1474
|
-
|
|
1648
|
+
function EditIcon({ color, size = 16 }) {
|
|
1649
|
+
const strokeColor = color || "currentColor";
|
|
1650
|
+
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: /* @__PURE__ */ jsx("path", { d: "M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z" }) });
|
|
1475
1651
|
}
|
|
1476
|
-
function DeleteIcon() {
|
|
1477
|
-
|
|
1652
|
+
function DeleteIcon({ color, size = 16 }) {
|
|
1653
|
+
const strokeColor = color || "currentColor";
|
|
1654
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", "stroke-width": "2", style: { stroke: strokeColor, width: `${size}px`, minWidth: `${size}px`, height: `${size}px`, display: "block", flexShrink: 0 }, children: [
|
|
1478
1655
|
/* @__PURE__ */ jsx("polyline", { points: "3 6 5 6 21 6" }),
|
|
1479
1656
|
/* @__PURE__ */ jsx("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
|
|
1480
1657
|
] });
|
|
@@ -2472,7 +2649,14 @@ var PocketPingClient = class {
|
|
|
2472
2649
|
}
|
|
2473
2650
|
connectSSE() {
|
|
2474
2651
|
if (!this.session) return;
|
|
2475
|
-
const
|
|
2652
|
+
const params = new URLSearchParams({
|
|
2653
|
+
sessionId: this.session.sessionId
|
|
2654
|
+
});
|
|
2655
|
+
const lastEventTimestamp = this.getLastEventTimestamp();
|
|
2656
|
+
if (lastEventTimestamp) {
|
|
2657
|
+
params.set("after", lastEventTimestamp);
|
|
2658
|
+
}
|
|
2659
|
+
const sseUrl = this.config.endpoint.replace(/\/$/, "") + `/stream?${params.toString()}`;
|
|
2476
2660
|
try {
|
|
2477
2661
|
this.sse = new EventSource(sseUrl);
|
|
2478
2662
|
const connectionTimeout = setTimeout(() => {
|
|
@@ -2527,6 +2711,19 @@ var PocketPingClient = class {
|
|
|
2527
2711
|
handleRealtimeEvent(event) {
|
|
2528
2712
|
this.handleWebSocketEvent(event);
|
|
2529
2713
|
}
|
|
2714
|
+
getLastEventTimestamp() {
|
|
2715
|
+
if (!this.session) return null;
|
|
2716
|
+
let latest = null;
|
|
2717
|
+
for (const msg of this.session.messages) {
|
|
2718
|
+
const candidates = [msg.timestamp, msg.editedAt, msg.deletedAt, msg.deliveredAt, msg.readAt].filter(Boolean).map((value) => new Date(value)).filter((date) => !isNaN(date.getTime()));
|
|
2719
|
+
for (const date of candidates) {
|
|
2720
|
+
if (!latest || date > latest) {
|
|
2721
|
+
latest = date;
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
return latest ? latest.toISOString() : null;
|
|
2726
|
+
}
|
|
2530
2727
|
handleWebSocketEvent(event) {
|
|
2531
2728
|
switch (event.type) {
|
|
2532
2729
|
case "message":
|
|
@@ -2549,12 +2746,41 @@ var PocketPingClient = class {
|
|
|
2549
2746
|
}
|
|
2550
2747
|
if (existingIndex >= 0) {
|
|
2551
2748
|
const existing = this.session.messages[existingIndex];
|
|
2749
|
+
let updated = false;
|
|
2552
2750
|
if (message.status && message.status !== existing.status) {
|
|
2553
2751
|
existing.status = message.status;
|
|
2554
|
-
|
|
2555
|
-
if (message.
|
|
2752
|
+
updated = true;
|
|
2753
|
+
if (message.deliveredAt) {
|
|
2754
|
+
existing.deliveredAt = message.deliveredAt;
|
|
2755
|
+
}
|
|
2756
|
+
if (message.readAt) {
|
|
2757
|
+
existing.readAt = message.readAt;
|
|
2758
|
+
}
|
|
2556
2759
|
this.emit("read", { messageIds: [message.id], status: message.status });
|
|
2557
2760
|
}
|
|
2761
|
+
if (message.content !== void 0 && message.content !== existing.content) {
|
|
2762
|
+
existing.content = message.content;
|
|
2763
|
+
updated = true;
|
|
2764
|
+
}
|
|
2765
|
+
if (message.editedAt !== void 0 && message.editedAt !== existing.editedAt) {
|
|
2766
|
+
existing.editedAt = message.editedAt;
|
|
2767
|
+
updated = true;
|
|
2768
|
+
}
|
|
2769
|
+
if (message.deletedAt !== void 0 && message.deletedAt !== existing.deletedAt) {
|
|
2770
|
+
existing.deletedAt = message.deletedAt;
|
|
2771
|
+
updated = true;
|
|
2772
|
+
}
|
|
2773
|
+
if (message.replyTo !== void 0) {
|
|
2774
|
+
existing.replyTo = message.replyTo;
|
|
2775
|
+
updated = true;
|
|
2776
|
+
}
|
|
2777
|
+
if (message.attachments !== void 0) {
|
|
2778
|
+
existing.attachments = message.attachments;
|
|
2779
|
+
updated = true;
|
|
2780
|
+
}
|
|
2781
|
+
if (updated) {
|
|
2782
|
+
this.emit("message", existing);
|
|
2783
|
+
}
|
|
2558
2784
|
} else {
|
|
2559
2785
|
this.session.messages.push(message);
|
|
2560
2786
|
this.emit("message", message);
|
|
@@ -2593,6 +2819,29 @@ var PocketPingClient = class {
|
|
|
2593
2819
|
}
|
|
2594
2820
|
this.emit("read", readData);
|
|
2595
2821
|
break;
|
|
2822
|
+
case "message_edited":
|
|
2823
|
+
if (this.session) {
|
|
2824
|
+
const editData = event.data;
|
|
2825
|
+
const msgIndex = this.session.messages.findIndex((m) => m.id === editData.messageId);
|
|
2826
|
+
if (msgIndex >= 0) {
|
|
2827
|
+
const existing = this.session.messages[msgIndex];
|
|
2828
|
+
existing.content = editData.content;
|
|
2829
|
+
existing.editedAt = editData.editedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
2830
|
+
this.emit("message", existing);
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2833
|
+
break;
|
|
2834
|
+
case "message_deleted":
|
|
2835
|
+
if (this.session) {
|
|
2836
|
+
const deleteData = event.data;
|
|
2837
|
+
const msgIndex = this.session.messages.findIndex((m) => m.id === deleteData.messageId);
|
|
2838
|
+
if (msgIndex >= 0) {
|
|
2839
|
+
const existing = this.session.messages[msgIndex];
|
|
2840
|
+
existing.deletedAt = deleteData.deletedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
2841
|
+
this.emit("message", existing);
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2844
|
+
break;
|
|
2596
2845
|
case "event":
|
|
2597
2846
|
const customEvent = event.data;
|
|
2598
2847
|
this.emitCustomEvent(customEvent);
|
|
@@ -2652,11 +2901,45 @@ var PocketPingClient = class {
|
|
|
2652
2901
|
const poll = async () => {
|
|
2653
2902
|
if (!this.session) return;
|
|
2654
2903
|
try {
|
|
2655
|
-
const
|
|
2656
|
-
const newMessages = await this.fetchMessages(
|
|
2904
|
+
const lastEventTimestamp = this.getLastEventTimestamp();
|
|
2905
|
+
const newMessages = await this.fetchMessages(lastEventTimestamp ?? void 0);
|
|
2657
2906
|
this.pollingFailures = 0;
|
|
2658
2907
|
for (const message of newMessages) {
|
|
2659
|
-
|
|
2908
|
+
const existingIndex = this.session.messages.findIndex((m) => m.id === message.id);
|
|
2909
|
+
if (existingIndex >= 0) {
|
|
2910
|
+
const existing = this.session.messages[existingIndex];
|
|
2911
|
+
let updated = false;
|
|
2912
|
+
if (message.status && message.status !== existing.status) {
|
|
2913
|
+
existing.status = message.status;
|
|
2914
|
+
updated = true;
|
|
2915
|
+
if (message.deliveredAt) existing.deliveredAt = message.deliveredAt;
|
|
2916
|
+
if (message.readAt) existing.readAt = message.readAt;
|
|
2917
|
+
this.emit("read", { messageIds: [message.id], status: message.status });
|
|
2918
|
+
}
|
|
2919
|
+
if (message.content !== void 0 && message.content !== existing.content) {
|
|
2920
|
+
existing.content = message.content;
|
|
2921
|
+
updated = true;
|
|
2922
|
+
}
|
|
2923
|
+
if (message.editedAt !== void 0 && message.editedAt !== existing.editedAt) {
|
|
2924
|
+
existing.editedAt = message.editedAt;
|
|
2925
|
+
updated = true;
|
|
2926
|
+
}
|
|
2927
|
+
if (message.deletedAt !== void 0 && message.deletedAt !== existing.deletedAt) {
|
|
2928
|
+
existing.deletedAt = message.deletedAt;
|
|
2929
|
+
updated = true;
|
|
2930
|
+
}
|
|
2931
|
+
if (message.replyTo !== void 0) {
|
|
2932
|
+
existing.replyTo = message.replyTo;
|
|
2933
|
+
updated = true;
|
|
2934
|
+
}
|
|
2935
|
+
if (message.attachments !== void 0) {
|
|
2936
|
+
existing.attachments = message.attachments;
|
|
2937
|
+
updated = true;
|
|
2938
|
+
}
|
|
2939
|
+
if (updated) {
|
|
2940
|
+
this.emit("message", existing);
|
|
2941
|
+
}
|
|
2942
|
+
} else {
|
|
2660
2943
|
this.session.messages.push(message);
|
|
2661
2944
|
this.emit("message", message);
|
|
2662
2945
|
this.config.onMessage?.(message);
|