@realtimexsco/live-chat 1.3.1 → 1.3.2
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 +29 -1809
- package/dist/index.cjs +84 -85
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +84 -85
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -555,7 +555,7 @@ var init_group_display_helpers = __esm({
|
|
|
555
555
|
});
|
|
556
556
|
|
|
557
557
|
// src/store/helpers/message.helpers.ts
|
|
558
|
-
var getMessageSenderId, extractMessageData, mergeLastMessage, messageHasPreviewBody, getLatestMessageFromList, isOwnMessage, getMessageContent, getMessageTimestamp,
|
|
558
|
+
var getMessageSenderId, extractMessageData, statusRank, preferHigherStatus, mergeLastMessage, messageHasPreviewBody, getLatestMessageFromList, isOwnMessage, getMessageContent, getMessageTimestamp, resolveMessageStatus, mergeChatMessages;
|
|
559
559
|
var init_message_helpers = __esm({
|
|
560
560
|
"src/store/helpers/message.helpers.ts"() {
|
|
561
561
|
getMessageSenderId = (message) => String(message?.sender?._id || message?.sender?.id || message?.senderId || message?.fromUserId || message?.sender || "");
|
|
@@ -570,21 +570,32 @@ var init_message_helpers = __esm({
|
|
|
570
570
|
const caption = payload.caption ?? payload.message?.caption ?? null;
|
|
571
571
|
return { messageId, content, conversationId, status, isPinned, isStarred, attachmentId, caption };
|
|
572
572
|
};
|
|
573
|
+
statusRank = { sent: 0, delivered: 1, read: 2 };
|
|
574
|
+
preferHigherStatus = (base, incoming) => {
|
|
575
|
+
const baseRank = statusRank[base?.status] ?? 0;
|
|
576
|
+
const incomingRank = statusRank[incoming?.status] ?? 0;
|
|
577
|
+
if (incomingRank > baseRank) {
|
|
578
|
+
return { ...base, status: incoming.status };
|
|
579
|
+
}
|
|
580
|
+
return base;
|
|
581
|
+
};
|
|
573
582
|
mergeLastMessage = (existing, incoming) => {
|
|
574
583
|
if (!incoming) return existing ?? null;
|
|
575
584
|
if (!existing) return incoming;
|
|
576
585
|
const content = incoming.content?.trim() ? incoming.content : existing.content;
|
|
577
586
|
const createdAt = incoming.createdAt ?? incoming.timestamp ?? existing.createdAt ?? existing.timestamp;
|
|
578
|
-
const
|
|
579
|
-
const
|
|
580
|
-
const newer = incomingTime >= existingTime ? incoming : existing;
|
|
587
|
+
const incomingSenderId = getMessageSenderId(incoming);
|
|
588
|
+
const resolvedSender = incomingSenderId ? incoming.sender ?? incoming.senderId ?? incoming.fromUserId : existing.sender ?? existing.senderId ?? existing.fromUserId ?? incoming.sender;
|
|
581
589
|
return {
|
|
582
590
|
...existing,
|
|
583
591
|
...incoming,
|
|
584
592
|
...content !== void 0 ? { content } : {},
|
|
585
593
|
...createdAt !== void 0 ? { createdAt } : {},
|
|
586
594
|
attachments: incoming.attachments?.length ? incoming.attachments : existing.attachments,
|
|
587
|
-
status:
|
|
595
|
+
status: preferHigherStatus(existing, incoming).status ?? existing.status ?? incoming.status,
|
|
596
|
+
...resolvedSender !== void 0 ? { sender: resolvedSender } : {},
|
|
597
|
+
senderId: incoming.senderId ?? existing.senderId,
|
|
598
|
+
fromUserId: incoming.fromUserId ?? existing.fromUserId
|
|
588
599
|
};
|
|
589
600
|
};
|
|
590
601
|
messageHasPreviewBody = (message) => Boolean(String(message?.content || "").trim()) || Array.isArray(message?.attachments) && message.attachments.length > 0;
|
|
@@ -607,15 +618,6 @@ var init_message_helpers = __esm({
|
|
|
607
618
|
const time = value ? new Date(value).getTime() : NaN;
|
|
608
619
|
return Number.isFinite(time) ? time : 0;
|
|
609
620
|
};
|
|
610
|
-
statusRank = { sent: 0, delivered: 1, read: 2 };
|
|
611
|
-
preferHigherStatus = (base, incoming) => {
|
|
612
|
-
const baseRank = statusRank[base?.status] ?? 0;
|
|
613
|
-
const incomingRank = statusRank[incoming?.status] ?? 0;
|
|
614
|
-
if (incomingRank > baseRank) {
|
|
615
|
-
return { ...base, status: incoming.status };
|
|
616
|
-
}
|
|
617
|
-
return base;
|
|
618
|
-
};
|
|
619
621
|
resolveMessageStatus = (message, conversation, loggedUserId) => {
|
|
620
622
|
const existing = message?.status || "sent";
|
|
621
623
|
if (!loggedUserId || !isOwnMessage(message, loggedUserId)) return existing;
|
|
@@ -790,7 +792,7 @@ var init_unread_helpers = __esm({
|
|
|
790
792
|
});
|
|
791
793
|
|
|
792
794
|
// src/store/helpers/conversation.helpers.ts
|
|
793
|
-
var findConversationIdByMessageId, isGroupConversation, normalizeConversationRecord, resolveConversationLastMessage, syncConversationLastMessage, upsertConversationInList, findConversationById, findConversationForChannel, resolveConversationIdForChannel;
|
|
795
|
+
var findConversationIdByMessageId, applyMessageStatusToStore, isGroupConversation, normalizeConversationRecord, resolveConversationLastMessage, syncConversationLastMessage, upsertConversationInList, findConversationById, findConversationIdByLastMessageId, findConversationForChannel, resolveConversationIdForChannel;
|
|
794
796
|
var init_conversation_helpers = __esm({
|
|
795
797
|
"src/store/helpers/conversation.helpers.ts"() {
|
|
796
798
|
init_group_display_helpers();
|
|
@@ -804,6 +806,40 @@ var init_conversation_helpers = __esm({
|
|
|
804
806
|
)
|
|
805
807
|
);
|
|
806
808
|
};
|
|
809
|
+
applyMessageStatusToStore = (state, messageId, status, conversationId) => {
|
|
810
|
+
const normalizedMessageId = String(messageId);
|
|
811
|
+
const resolvedConversationId = conversationId ? String(conversationId) : findConversationIdByMessageId(state.messagesByConversation, normalizedMessageId) || findConversationIdByLastMessageId(state.conversations, normalizedMessageId) || null;
|
|
812
|
+
const nextConversations = state.conversations.map((conversation) => {
|
|
813
|
+
const lastMessageId = String(
|
|
814
|
+
conversation?.lastMessage?._id || conversation?.lastMessage?.id || ""
|
|
815
|
+
);
|
|
816
|
+
if (lastMessageId !== normalizedMessageId) return conversation;
|
|
817
|
+
return {
|
|
818
|
+
...conversation,
|
|
819
|
+
lastMessage: mergeLastMessage(conversation.lastMessage, { status })
|
|
820
|
+
};
|
|
821
|
+
});
|
|
822
|
+
const nextMessagesByConversation = { ...state.messagesByConversation };
|
|
823
|
+
const patchMessages = (messages) => messages.map(
|
|
824
|
+
(message) => String(message._id || message.id) === normalizedMessageId ? preferHigherStatus(message, { status }) : message
|
|
825
|
+
);
|
|
826
|
+
if (resolvedConversationId && nextMessagesByConversation[resolvedConversationId]) {
|
|
827
|
+
nextMessagesByConversation[resolvedConversationId] = patchMessages(
|
|
828
|
+
nextMessagesByConversation[resolvedConversationId]
|
|
829
|
+
);
|
|
830
|
+
} else {
|
|
831
|
+
for (const cid of Object.keys(nextMessagesByConversation)) {
|
|
832
|
+
const patched = patchMessages(nextMessagesByConversation[cid]);
|
|
833
|
+
if (patched !== nextMessagesByConversation[cid]) {
|
|
834
|
+
nextMessagesByConversation[cid] = patched;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
return {
|
|
839
|
+
conversations: nextConversations,
|
|
840
|
+
messagesByConversation: nextMessagesByConversation
|
|
841
|
+
};
|
|
842
|
+
};
|
|
807
843
|
isGroupConversation = (conversation) => {
|
|
808
844
|
if (!conversation) return false;
|
|
809
845
|
return conversation.conversationType === "group" || !!conversation.isGroup;
|
|
@@ -893,6 +929,14 @@ var init_conversation_helpers = __esm({
|
|
|
893
929
|
if (!conversationId) return void 0;
|
|
894
930
|
return conversations.find((c) => String(c._id) === String(conversationId));
|
|
895
931
|
};
|
|
932
|
+
findConversationIdByLastMessageId = (conversations, messageId) => {
|
|
933
|
+
if (!messageId) return null;
|
|
934
|
+
const normalizedMessageId = String(messageId);
|
|
935
|
+
const match = conversations.find(
|
|
936
|
+
(conversation) => String(conversation?.lastMessage?._id || conversation?.lastMessage?.id || "") === normalizedMessageId
|
|
937
|
+
);
|
|
938
|
+
return match?._id ? String(match._id) : null;
|
|
939
|
+
};
|
|
896
940
|
findConversationForChannel = (channel, loggedUserId, conversations) => {
|
|
897
941
|
if (!channel || !loggedUserId) return void 0;
|
|
898
942
|
if (channel.conversationId) {
|
|
@@ -2965,28 +3009,16 @@ var init_dm_actions = __esm({
|
|
|
2965
3009
|
},
|
|
2966
3010
|
receivedStatusUpdate: (payload) => {
|
|
2967
3011
|
const data = extractMessageData(payload);
|
|
2968
|
-
let { conversationId } = data;
|
|
2969
3012
|
const { messageId, status } = data;
|
|
2970
|
-
|
|
3013
|
+
let { conversationId } = data;
|
|
3014
|
+
if (!messageId || !status) return;
|
|
2971
3015
|
set({ lastStatusUpdate: payload });
|
|
2972
3016
|
if (!conversationId) {
|
|
2973
|
-
conversationId = findConversationIdByMessageId(get().messagesByConversation, messageId);
|
|
3017
|
+
conversationId = findConversationIdByMessageId(get().messagesByConversation, messageId) || findConversationIdByLastMessageId(get().conversations, messageId) || void 0;
|
|
2974
3018
|
}
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
return {
|
|
2979
|
-
messagesByConversation: {
|
|
2980
|
-
...state.messagesByConversation,
|
|
2981
|
-
[conversationId]: messages.map(
|
|
2982
|
-
(m) => String(m._id || m.id) === String(messageId) ? preferHigherStatus(m, { status }) : m
|
|
2983
|
-
)
|
|
2984
|
-
},
|
|
2985
|
-
conversations: state.conversations.map(
|
|
2986
|
-
(c) => String(c._id) === String(conversationId) && c.lastMessage && String(c.lastMessage._id || c.lastMessage.id) === String(messageId) ? { ...c, lastMessage: mergeLastMessage(c.lastMessage, { status }) } : c
|
|
2987
|
-
)
|
|
2988
|
-
};
|
|
2989
|
-
});
|
|
3019
|
+
set((state) => ({
|
|
3020
|
+
...applyMessageStatusToStore(state, String(messageId), status, conversationId)
|
|
3021
|
+
}));
|
|
2990
3022
|
},
|
|
2991
3023
|
receivedDMMarkRead: (payload) => {
|
|
2992
3024
|
const { conversationId } = payload;
|
|
@@ -3247,25 +3279,14 @@ var init_group_actions2 = __esm({
|
|
|
3247
3279
|
let { conversationId } = data;
|
|
3248
3280
|
const { messageId, status } = data;
|
|
3249
3281
|
set({ lastStatusUpdate: payload });
|
|
3282
|
+
if (!status) return;
|
|
3250
3283
|
if (messageId) {
|
|
3251
3284
|
if (!conversationId) {
|
|
3252
|
-
conversationId = findConversationIdByMessageId(get().messagesByConversation, messageId);
|
|
3285
|
+
conversationId = findConversationIdByMessageId(get().messagesByConversation, messageId) || findConversationIdByLastMessageId(get().conversations, messageId) || void 0;
|
|
3253
3286
|
}
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
return {
|
|
3258
|
-
messagesByConversation: {
|
|
3259
|
-
...state.messagesByConversation,
|
|
3260
|
-
[conversationId]: messages.map(
|
|
3261
|
-
(m) => String(m._id || m.id) === String(messageId) ? { ...m, status } : m
|
|
3262
|
-
)
|
|
3263
|
-
},
|
|
3264
|
-
conversations: state.conversations.map(
|
|
3265
|
-
(c) => String(c._id) === String(conversationId) && c.lastMessage && String(c.lastMessage._id || c.lastMessage.id) === String(messageId) ? { ...c, lastMessage: { ...c.lastMessage, status } } : c
|
|
3266
|
-
)
|
|
3267
|
-
};
|
|
3268
|
-
});
|
|
3287
|
+
set((state) => ({
|
|
3288
|
+
...applyMessageStatusToStore(state, String(messageId), status, conversationId)
|
|
3289
|
+
}));
|
|
3269
3290
|
return;
|
|
3270
3291
|
}
|
|
3271
3292
|
if (conversationId && status === "read") {
|
|
@@ -3280,7 +3301,7 @@ var init_group_actions2 = __esm({
|
|
|
3280
3301
|
if (String(c._id) !== String(conversationId)) return c;
|
|
3281
3302
|
let nextLastMessage = c.lastMessage;
|
|
3282
3303
|
if (nextLastMessage && String(nextLastMessage.sender?._id || nextLastMessage.sender) === String(myId)) {
|
|
3283
|
-
nextLastMessage =
|
|
3304
|
+
nextLastMessage = mergeLastMessage(nextLastMessage, { status: "read" });
|
|
3284
3305
|
}
|
|
3285
3306
|
return { ...c, lastMessage: nextLastMessage };
|
|
3286
3307
|
});
|
|
@@ -6795,15 +6816,13 @@ function useChannelList({ debouncedSearch = "" }) {
|
|
|
6795
6816
|
}
|
|
6796
6817
|
}
|
|
6797
6818
|
const draftPreview = getConversationDraftPreview(conversationId);
|
|
6798
|
-
const
|
|
6799
|
-
|
|
6800
|
-
);
|
|
6801
|
-
const
|
|
6802
|
-
|
|
6803
|
-
resolvedLastMessage
|
|
6804
|
-
|
|
6805
|
-
loggedUserDetails?._id
|
|
6806
|
-
);
|
|
6819
|
+
const storedLastMessage = c.lastMessage;
|
|
6820
|
+
const storedLastMessageId = String(storedLastMessage?._id || storedLastMessage?.id || "");
|
|
6821
|
+
const resolvedLastMessageId = String(resolvedLastMessage?._id || resolvedLastMessage?.id || "");
|
|
6822
|
+
const lastMessageStatus = storedLastMessageId && resolvedLastMessageId && storedLastMessageId === resolvedLastMessageId ? preferHigherStatus(
|
|
6823
|
+
{ status: storedLastMessage?.status },
|
|
6824
|
+
{ status: resolvedLastMessage?.status }
|
|
6825
|
+
).status ?? storedLastMessage?.status ?? resolvedLastMessage?.status : storedLastMessage?.status;
|
|
6807
6826
|
return {
|
|
6808
6827
|
id: isGroup ? conversationId : otherParticipantId,
|
|
6809
6828
|
conversationId,
|
|
@@ -6817,12 +6836,11 @@ function useChannelList({ debouncedSearch = "" }) {
|
|
|
6817
6836
|
unreadCount,
|
|
6818
6837
|
isTyping,
|
|
6819
6838
|
draftPreview,
|
|
6820
|
-
isOwnLastMessage,
|
|
6821
6839
|
pinnedCount: c.pinnedCount,
|
|
6822
6840
|
starredCount: c.starredCount,
|
|
6823
6841
|
lastMessage: {
|
|
6824
6842
|
content: lastMessageContent,
|
|
6825
|
-
timestamp: resolvedLastMessage?.createdAt ? formatSidebarTime(resolvedLastMessage.createdAt) : "",
|
|
6843
|
+
timestamp: resolvedLastMessage?.createdAt ? formatSidebarTime(resolvedLastMessage.createdAt) : c.lastMessage?.createdAt ? formatSidebarTime(c.lastMessage.createdAt) : "",
|
|
6826
6844
|
status: lastMessageStatus,
|
|
6827
6845
|
sender: "User"
|
|
6828
6846
|
}
|
|
@@ -6851,7 +6869,7 @@ function useChannelList({ debouncedSearch = "" }) {
|
|
|
6851
6869
|
init_store_helpers();
|
|
6852
6870
|
function ChannelListItem({ channel, activeChannel, onChannelSelect }) {
|
|
6853
6871
|
const isActive = activeChannel?.conversationId ? String(activeChannel.conversationId) === String(channel.conversationId) : activeChannel?.id === channel.id;
|
|
6854
|
-
const showReadReceipt = channel.
|
|
6872
|
+
const showReadReceipt = !!channel.lastMessage?.status && !channel.unreadCount && !channel.isTyping && !channel.draftPreview;
|
|
6855
6873
|
const lastStatus = channel.lastMessage?.status;
|
|
6856
6874
|
return /* @__PURE__ */ jsxs(
|
|
6857
6875
|
"div",
|
|
@@ -8520,24 +8538,11 @@ function GroupSenderName({ name, className }) {
|
|
|
8520
8538
|
}
|
|
8521
8539
|
|
|
8522
8540
|
// src/chat/lib/chat-message-bubble.ts
|
|
8523
|
-
function getBubbleCornerClasses(
|
|
8524
|
-
|
|
8525
|
-
return cn(
|
|
8526
|
-
"rounded-tl-[18px] rounded-bl-[18px]",
|
|
8527
|
-
isGroupedWithPrev ? "rounded-tr-[6px]" : "rounded-tr-[18px]",
|
|
8528
|
-
isGroupedWithNext ? "rounded-br-[6px]" : "rounded-br-[4px]"
|
|
8529
|
-
);
|
|
8530
|
-
}
|
|
8531
|
-
return cn(
|
|
8532
|
-
"rounded-tr-[18px] rounded-br-[18px]",
|
|
8533
|
-
isGroupedWithPrev ? "rounded-tl-[6px]" : "rounded-tl-[18px]",
|
|
8534
|
-
isGroupedWithNext ? "rounded-bl-[6px]" : "rounded-bl-[4px]"
|
|
8535
|
-
);
|
|
8541
|
+
function getBubbleCornerClasses() {
|
|
8542
|
+
return "rounded-tl-[18px] rounded-tr-[18px] rounded-br-[18px] rounded-bl-none";
|
|
8536
8543
|
}
|
|
8537
8544
|
function getChatBubbleClasses({
|
|
8538
8545
|
isSender = false,
|
|
8539
|
-
isGroupedWithPrev = false,
|
|
8540
|
-
isGroupedWithNext = false,
|
|
8541
8546
|
surface,
|
|
8542
8547
|
className
|
|
8543
8548
|
}) {
|
|
@@ -8545,7 +8550,7 @@ function getChatBubbleClasses({
|
|
|
8545
8550
|
const isNeutral = resolvedSurface === "neutral";
|
|
8546
8551
|
return cn(
|
|
8547
8552
|
"relative",
|
|
8548
|
-
getBubbleCornerClasses(
|
|
8553
|
+
getBubbleCornerClasses(),
|
|
8549
8554
|
resolvedSurface === "sent" && "chat-bubble-sent bg-(--chat-theme) text-white",
|
|
8550
8555
|
resolvedSurface === "received" && "chat-bubble-received border border-(--chat-border)/60 bg-(--chat-incoming-bubble) text-(--chat-incoming-text)",
|
|
8551
8556
|
isNeutral && "chat-bubble-received border border-(--chat-border)/60 bg-(--chat-incoming-bubble) text-(--chat-incoming-text)",
|
|
@@ -10360,8 +10365,6 @@ function MessageAttachmentsView({
|
|
|
10360
10365
|
"relative w-full",
|
|
10361
10366
|
isBubbleLayout && getChatBubbleClasses({
|
|
10362
10367
|
isSender,
|
|
10363
|
-
isGroupedWithPrev,
|
|
10364
|
-
isGroupedWithNext,
|
|
10365
10368
|
surface: bubbleSurface,
|
|
10366
10369
|
className: cn(
|
|
10367
10370
|
isImageOnlyBubble ? "p-0" : isForwarded ? "px-2 py-0.5" : "px-2.5 py-1"
|
|
@@ -13822,8 +13825,6 @@ function MessageItemTextBubble({
|
|
|
13822
13825
|
}) {
|
|
13823
13826
|
const bubbleClasses = (extra) => getChatBubbleClasses({
|
|
13824
13827
|
isSender,
|
|
13825
|
-
isGroupedWithPrev,
|
|
13826
|
-
isGroupedWithNext,
|
|
13827
13828
|
className: extra
|
|
13828
13829
|
});
|
|
13829
13830
|
return /* @__PURE__ */ jsxs(
|
|
@@ -14116,8 +14117,6 @@ function MessageItemView(props) {
|
|
|
14116
14117
|
const showMessageSelectionRadio = selectionMode && !isDeletedForEveryone && !!mid && !hasMultiAttachments;
|
|
14117
14118
|
const bubbleClasses = (extra) => getChatBubbleClasses({
|
|
14118
14119
|
isSender,
|
|
14119
|
-
isGroupedWithPrev,
|
|
14120
|
-
isGroupedWithNext,
|
|
14121
14120
|
className: extra
|
|
14122
14121
|
});
|
|
14123
14122
|
return /* @__PURE__ */ jsxs(
|
|
@@ -16871,7 +16870,7 @@ var DefaultChannelListItem = ({
|
|
|
16871
16870
|
onSelect
|
|
16872
16871
|
}) => {
|
|
16873
16872
|
const { slotClassName } = useChatCustomizationOptional();
|
|
16874
|
-
const showReadReceipt = channel.
|
|
16873
|
+
const showReadReceipt = !!channel.lastMessage?.status && !channel.unreadCount && !channel.isTyping && !channel.draftPreview;
|
|
16875
16874
|
const lastStatus = channel.lastMessage?.status;
|
|
16876
16875
|
return /* @__PURE__ */ jsxs(
|
|
16877
16876
|
"div",
|