@realtimexsco/live-chat 1.3.3 → 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 +1042 -329
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +69 -1
- package/dist/index.d.ts +69 -1
- package/dist/index.mjs +1017 -331
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +93 -59
- package/package.json +5 -3
package/dist/index.cjs
CHANGED
|
@@ -15,12 +15,31 @@ var reactDom = require('react-dom');
|
|
|
15
15
|
var lucideReact = require('lucide-react');
|
|
16
16
|
var classVarianceAuthority = require('class-variance-authority');
|
|
17
17
|
var EmojiPicker = require('emoji-picker-react');
|
|
18
|
+
var reactDayPicker = require('react-day-picker');
|
|
18
19
|
var reactHotToast = require('react-hot-toast');
|
|
19
20
|
|
|
20
21
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
21
22
|
|
|
23
|
+
function _interopNamespace(e) {
|
|
24
|
+
if (e && e.__esModule) return e;
|
|
25
|
+
var n = Object.create(null);
|
|
26
|
+
if (e) {
|
|
27
|
+
Object.keys(e).forEach(function (k) {
|
|
28
|
+
if (k !== 'default') {
|
|
29
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
30
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () { return e[k]; }
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
n.default = e;
|
|
38
|
+
return Object.freeze(n);
|
|
39
|
+
}
|
|
40
|
+
|
|
22
41
|
var axios__default = /*#__PURE__*/_interopDefault(axios);
|
|
23
|
-
var
|
|
42
|
+
var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
|
|
24
43
|
var EmojiPicker__default = /*#__PURE__*/_interopDefault(EmojiPicker);
|
|
25
44
|
|
|
26
45
|
var __defProp = Object.defineProperty;
|
|
@@ -570,7 +589,7 @@ var init_message_helpers = __esm({
|
|
|
570
589
|
"src/store/helpers/message.helpers.ts"() {
|
|
571
590
|
getMessageSenderId = (message) => String(message?.sender?._id || message?.sender?.id || message?.senderId || message?.fromUserId || message?.sender || "");
|
|
572
591
|
extractMessageData = (payload) => {
|
|
573
|
-
const
|
|
592
|
+
const messageId2 = payload.messageId || payload._id || payload.message?._id || payload.message?.id;
|
|
574
593
|
const content = payload.content || payload.message?.content;
|
|
575
594
|
const conversationId = payload.conversationId || payload.conversation_id || payload.message?.conversationId || payload.message?.conversation_id;
|
|
576
595
|
const status = payload.status || payload.message?.status;
|
|
@@ -578,7 +597,7 @@ var init_message_helpers = __esm({
|
|
|
578
597
|
const isStarred = payload.isStarred ?? payload.message?.isStarred;
|
|
579
598
|
const attachmentId = payload.attachmentId || payload.unpinAttachmentId || null;
|
|
580
599
|
const caption = payload.caption ?? payload.message?.caption ?? null;
|
|
581
|
-
return { messageId, content, conversationId, status, isPinned, isStarred, attachmentId, caption };
|
|
600
|
+
return { messageId: messageId2, content, conversationId, status, isPinned, isStarred, attachmentId, caption };
|
|
582
601
|
};
|
|
583
602
|
statusRank = { sent: 0, delivered: 1, read: 2 };
|
|
584
603
|
preferHigherStatus = (base, incoming) => {
|
|
@@ -809,15 +828,15 @@ var init_conversation_helpers = __esm({
|
|
|
809
828
|
init_message_helpers();
|
|
810
829
|
init_participant_helpers();
|
|
811
830
|
init_unread_helpers();
|
|
812
|
-
findConversationIdByMessageId = (messagesByConversation,
|
|
831
|
+
findConversationIdByMessageId = (messagesByConversation, messageId2) => {
|
|
813
832
|
return Object.keys(messagesByConversation).find(
|
|
814
833
|
(cid) => messagesByConversation[cid].some(
|
|
815
|
-
(m) => String(m._id || m.id) === String(
|
|
834
|
+
(m) => String(m._id || m.id) === String(messageId2)
|
|
816
835
|
)
|
|
817
836
|
);
|
|
818
837
|
};
|
|
819
|
-
applyMessageStatusToStore = (state,
|
|
820
|
-
const normalizedMessageId = String(
|
|
838
|
+
applyMessageStatusToStore = (state, messageId2, status, conversationId) => {
|
|
839
|
+
const normalizedMessageId = String(messageId2);
|
|
821
840
|
const resolvedConversationId = conversationId ? String(conversationId) : findConversationIdByMessageId(state.messagesByConversation, normalizedMessageId) || findConversationIdByLastMessageId(state.conversations, normalizedMessageId) || null;
|
|
822
841
|
const nextConversations = state.conversations.map((conversation) => {
|
|
823
842
|
const lastMessageId = String(
|
|
@@ -860,6 +879,9 @@ var init_conversation_helpers = __esm({
|
|
|
860
879
|
const mergedParticipants = conversation.participants !== void 0 ? mergeConversationParticipants(existing?.participants, conversation.participants) : existing?.participants ?? conversation.participants;
|
|
861
880
|
const isGroup = isGroupConversation(conversation) || isGroupConversation(existing);
|
|
862
881
|
const resolvedGroupImage = resolveGroupImage(conversation) || resolveGroupImage(existing);
|
|
882
|
+
const incomingGroupName = typeof conversation.groupName === "string" && conversation.groupName.trim() || typeof conversation.name === "string" && conversation.name.trim() || "";
|
|
883
|
+
const existingGroupName = typeof existing?.groupName === "string" && existing.groupName.trim() || typeof existing?.name === "string" && existing.name.trim() || "";
|
|
884
|
+
const resolvedGroupName = incomingGroupName || existingGroupName || void 0;
|
|
863
885
|
return {
|
|
864
886
|
...existing,
|
|
865
887
|
...conversation,
|
|
@@ -867,7 +889,10 @@ var init_conversation_helpers = __esm({
|
|
|
867
889
|
isGroup,
|
|
868
890
|
isBlocked: resolvedBlocked,
|
|
869
891
|
lastMessage: mergeLastMessage(existing?.lastMessage, conversation.lastMessage),
|
|
870
|
-
...isGroup
|
|
892
|
+
...isGroup ? {
|
|
893
|
+
...resolvedGroupName ? { groupName: resolvedGroupName, name: resolvedGroupName } : {},
|
|
894
|
+
...resolvedGroupImage ? { image: resolvedGroupImage, groupImage: resolvedGroupImage } : {}
|
|
895
|
+
} : {}
|
|
871
896
|
};
|
|
872
897
|
};
|
|
873
898
|
resolveConversationLastMessage = (conversation, messagesByConversation) => {
|
|
@@ -939,9 +964,9 @@ var init_conversation_helpers = __esm({
|
|
|
939
964
|
if (!conversationId) return void 0;
|
|
940
965
|
return conversations.find((c) => String(c._id) === String(conversationId));
|
|
941
966
|
};
|
|
942
|
-
findConversationIdByLastMessageId = (conversations,
|
|
943
|
-
if (!
|
|
944
|
-
const normalizedMessageId = String(
|
|
967
|
+
findConversationIdByLastMessageId = (conversations, messageId2) => {
|
|
968
|
+
if (!messageId2) return null;
|
|
969
|
+
const normalizedMessageId = String(messageId2);
|
|
945
970
|
const match = conversations.find(
|
|
946
971
|
(conversation) => String(conversation?.lastMessage?._id || conversation?.lastMessage?.id || "") === normalizedMessageId
|
|
947
972
|
);
|
|
@@ -1360,7 +1385,7 @@ var init_api_constants = __esm({
|
|
|
1360
1385
|
ADD_REMOVE_MEMBERS: "/conversation/group/participants/add-remove",
|
|
1361
1386
|
ADD_REMOVE_ADMINS: "/conversation/group/admins/add-remove",
|
|
1362
1387
|
SEARCH_MESSAGES: "/message/search-messages",
|
|
1363
|
-
SEARCH_MESSAGES_CONTEXT: (
|
|
1388
|
+
SEARCH_MESSAGES_CONTEXT: (messageId2) => `/message/searched-message/context?messageId=${messageId2}`,
|
|
1364
1389
|
BLOCK_UNBLOCK_USER: "/user/block-unblock"
|
|
1365
1390
|
}
|
|
1366
1391
|
};
|
|
@@ -1504,9 +1529,9 @@ var init_messages_api = __esm({
|
|
|
1504
1529
|
throw error;
|
|
1505
1530
|
}
|
|
1506
1531
|
};
|
|
1507
|
-
searchMessagesContext = async (
|
|
1532
|
+
searchMessagesContext = async (messageId2) => {
|
|
1508
1533
|
try {
|
|
1509
|
-
const response = await apiClient.get(API_ENDPOINTS.GROUP.SEARCH_MESSAGES_CONTEXT(
|
|
1534
|
+
const response = await apiClient.get(API_ENDPOINTS.GROUP.SEARCH_MESSAGES_CONTEXT(messageId2));
|
|
1510
1535
|
return response.data;
|
|
1511
1536
|
} catch (error) {
|
|
1512
1537
|
console.error("Search messages context failed:", error);
|
|
@@ -1632,24 +1657,24 @@ var init_forwardPending_store = __esm({
|
|
|
1632
1657
|
"src/store/forwardPending.store.ts"() {
|
|
1633
1658
|
pendingForwards = /* @__PURE__ */ new Map();
|
|
1634
1659
|
lastPendingMessageId = null;
|
|
1635
|
-
setPendingForward = (
|
|
1636
|
-
if (!
|
|
1637
|
-
const key = String(
|
|
1660
|
+
setPendingForward = (messageId2, meta) => {
|
|
1661
|
+
if (!messageId2) return;
|
|
1662
|
+
const key = String(messageId2);
|
|
1638
1663
|
pendingForwards.set(key, meta);
|
|
1639
1664
|
lastPendingMessageId = key;
|
|
1640
1665
|
};
|
|
1641
|
-
peekPendingForward = (
|
|
1642
|
-
if (!
|
|
1643
|
-
return pendingForwards.get(String(
|
|
1666
|
+
peekPendingForward = (messageId2) => {
|
|
1667
|
+
if (!messageId2) return void 0;
|
|
1668
|
+
return pendingForwards.get(String(messageId2));
|
|
1644
1669
|
};
|
|
1645
1670
|
peekMostRecentPendingForward = () => {
|
|
1646
1671
|
if (!lastPendingMessageId) return void 0;
|
|
1647
1672
|
return pendingForwards.get(lastPendingMessageId);
|
|
1648
1673
|
};
|
|
1649
1674
|
getLastPendingForwardMessageId = () => lastPendingMessageId;
|
|
1650
|
-
clearPendingForward = (
|
|
1651
|
-
if (
|
|
1652
|
-
const key = String(
|
|
1675
|
+
clearPendingForward = (messageId2) => {
|
|
1676
|
+
if (messageId2) {
|
|
1677
|
+
const key = String(messageId2);
|
|
1653
1678
|
pendingForwards.delete(key);
|
|
1654
1679
|
if (lastPendingMessageId === key) lastPendingMessageId = null;
|
|
1655
1680
|
return;
|
|
@@ -2119,14 +2144,14 @@ var init_group_reaction_handlers = __esm({
|
|
|
2119
2144
|
return Array.from(map.values());
|
|
2120
2145
|
};
|
|
2121
2146
|
handleGroupReactionAddReceive = (set, get, payload) => {
|
|
2122
|
-
const
|
|
2147
|
+
const messageId2 = payload.messageId || payload._id;
|
|
2123
2148
|
const conversationId = payload.conversationId;
|
|
2124
|
-
if (!
|
|
2149
|
+
if (!messageId2) return;
|
|
2125
2150
|
set((state) => {
|
|
2126
|
-
const cid = conversationId || findConversationIdByMessageId(state.messagesByConversation,
|
|
2151
|
+
const cid = conversationId || findConversationIdByMessageId(state.messagesByConversation, messageId2);
|
|
2127
2152
|
if (!cid) return state;
|
|
2128
2153
|
const messages = state.messagesByConversation[cid] || [];
|
|
2129
|
-
const idx = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
2154
|
+
const idx = messages.findIndex((m) => String(m._id || m.id) === String(messageId2));
|
|
2130
2155
|
if (idx === -1) return state;
|
|
2131
2156
|
const nextMessages = [...messages];
|
|
2132
2157
|
const currentMsg = { ...nextMessages[idx] };
|
|
@@ -2144,20 +2169,20 @@ var init_group_reaction_handlers = __esm({
|
|
|
2144
2169
|
}
|
|
2145
2170
|
nextMessages[idx] = currentMsg;
|
|
2146
2171
|
return {
|
|
2147
|
-
lastReactionUpdate: { ...payload, messageId, action: "add", _v: Date.now() },
|
|
2172
|
+
lastReactionUpdate: { ...payload, messageId: messageId2, action: "add", _v: Date.now() },
|
|
2148
2173
|
messagesByConversation: { ...state.messagesByConversation, [cid]: nextMessages }
|
|
2149
2174
|
};
|
|
2150
2175
|
});
|
|
2151
2176
|
};
|
|
2152
2177
|
handleGroupReactionRemoveReceive = (set, get, payload) => {
|
|
2153
|
-
const
|
|
2178
|
+
const messageId2 = payload.messageId || payload._id;
|
|
2154
2179
|
const conversationId = payload.conversationId;
|
|
2155
|
-
if (!
|
|
2180
|
+
if (!messageId2) return;
|
|
2156
2181
|
set((state) => {
|
|
2157
|
-
const cid = conversationId || findConversationIdByMessageId(state.messagesByConversation,
|
|
2182
|
+
const cid = conversationId || findConversationIdByMessageId(state.messagesByConversation, messageId2);
|
|
2158
2183
|
if (!cid) return state;
|
|
2159
2184
|
const messages = state.messagesByConversation[cid] || [];
|
|
2160
|
-
const idx = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
2185
|
+
const idx = messages.findIndex((m) => String(m._id || m.id) === String(messageId2));
|
|
2161
2186
|
if (idx === -1) return state;
|
|
2162
2187
|
const nextMessages = [...messages];
|
|
2163
2188
|
const currentMsg = { ...nextMessages[idx] };
|
|
@@ -2174,7 +2199,7 @@ var init_group_reaction_handlers = __esm({
|
|
|
2174
2199
|
}
|
|
2175
2200
|
nextMessages[idx] = currentMsg;
|
|
2176
2201
|
return {
|
|
2177
|
-
lastReactionUpdate: { ...payload, messageId, action: "remove", _v: Date.now() },
|
|
2202
|
+
lastReactionUpdate: { ...payload, messageId: messageId2, action: "remove", _v: Date.now() },
|
|
2178
2203
|
messagesByConversation: { ...state.messagesByConversation, [cid]: nextMessages }
|
|
2179
2204
|
};
|
|
2180
2205
|
});
|
|
@@ -2204,14 +2229,14 @@ function removeMessageAttachment(message, attachmentId) {
|
|
|
2204
2229
|
if (attachments.length === message.attachments.length) return message;
|
|
2205
2230
|
return { ...message, attachments };
|
|
2206
2231
|
}
|
|
2207
|
-
function pinKey(
|
|
2208
|
-
return attachmentId ? `${
|
|
2232
|
+
function pinKey(messageId2, attachmentId) {
|
|
2233
|
+
return attachmentId ? `${messageId2}:${attachmentId}` : String(messageId2);
|
|
2209
2234
|
}
|
|
2210
|
-
function matchesPinEntry(entry,
|
|
2235
|
+
function matchesPinEntry(entry, messageId2, attachmentId) {
|
|
2211
2236
|
const entryMessageId = String(
|
|
2212
2237
|
entry?.messageId?._id || entry?.messageId || entry?._id || entry?.id || ""
|
|
2213
2238
|
);
|
|
2214
|
-
if (entryMessageId !== String(
|
|
2239
|
+
if (entryMessageId !== String(messageId2)) return false;
|
|
2215
2240
|
const entryAttachmentId = entry?.attachmentId ? String(entry.attachmentId) : null;
|
|
2216
2241
|
const targetAttachmentId = attachmentId ? String(attachmentId) : null;
|
|
2217
2242
|
return entryAttachmentId === targetAttachmentId;
|
|
@@ -2226,13 +2251,13 @@ function applyPinnedListToMessages(messages, pinnedMessage) {
|
|
|
2226
2251
|
)
|
|
2227
2252
|
);
|
|
2228
2253
|
return messages.map((message) => {
|
|
2229
|
-
const
|
|
2230
|
-
const hasWholeMessagePin = pinnedKeys.has(pinKey(
|
|
2254
|
+
const messageId2 = String(message._id || message.id);
|
|
2255
|
+
const hasWholeMessagePin = pinnedKeys.has(pinKey(messageId2, null));
|
|
2231
2256
|
const attachments = (message.attachments || []).map((att) => {
|
|
2232
2257
|
const attId = getAttachmentId(att);
|
|
2233
2258
|
return {
|
|
2234
2259
|
...att,
|
|
2235
|
-
isPinned: attId ? pinnedKeys.has(pinKey(
|
|
2260
|
+
isPinned: attId ? pinnedKeys.has(pinKey(messageId2, attId)) : !!att.isPinned
|
|
2236
2261
|
};
|
|
2237
2262
|
});
|
|
2238
2263
|
return {
|
|
@@ -2294,13 +2319,13 @@ var init_pin_handlers = __esm({
|
|
|
2294
2319
|
});
|
|
2295
2320
|
return;
|
|
2296
2321
|
}
|
|
2297
|
-
const { messageId, conversationId, isPinned, attachmentId } = extractMessageData(payload);
|
|
2298
|
-
if (!
|
|
2322
|
+
const { messageId: messageId2, conversationId, isPinned, attachmentId } = extractMessageData(payload);
|
|
2323
|
+
if (!messageId2 || !conversationId) return;
|
|
2299
2324
|
set((state) => {
|
|
2300
|
-
const sid = conversationId || findConversationIdByMessageId(state.messagesByConversation,
|
|
2325
|
+
const sid = conversationId || findConversationIdByMessageId(state.messagesByConversation, messageId2);
|
|
2301
2326
|
if (!sid) return state;
|
|
2302
2327
|
const messages = state.messagesByConversation[sid] || [];
|
|
2303
|
-
const index = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
2328
|
+
const index = messages.findIndex((m) => String(m._id || m.id) === String(messageId2));
|
|
2304
2329
|
let newMessagesByConversation = state.messagesByConversation;
|
|
2305
2330
|
const msg = index !== -1 ? messages[index] : null;
|
|
2306
2331
|
const wasPinned = attachmentId ? !!msg?.attachments?.some(
|
|
@@ -2322,9 +2347,9 @@ var init_pin_handlers = __esm({
|
|
|
2322
2347
|
const newPinnedByConv = { ...state.pinnedMessagesByConversation };
|
|
2323
2348
|
if (isPinned) {
|
|
2324
2349
|
const currentPinned = newPinnedByConv[sid] || [];
|
|
2325
|
-
if (!currentPinned.some((m) => matchesPinEntry(m,
|
|
2350
|
+
if (!currentPinned.some((m) => matchesPinEntry(m, messageId2, attachmentId || null))) {
|
|
2326
2351
|
const fullMsg = msg ? attachmentId ? {
|
|
2327
|
-
messageId,
|
|
2352
|
+
messageId: messageId2,
|
|
2328
2353
|
attachmentId,
|
|
2329
2354
|
attachment: msg.attachments?.find(
|
|
2330
2355
|
(att) => getAttachmentId(att) === String(attachmentId)
|
|
@@ -2336,7 +2361,7 @@ var init_pin_handlers = __esm({
|
|
|
2336
2361
|
}
|
|
2337
2362
|
} else {
|
|
2338
2363
|
newPinnedByConv[sid] = (newPinnedByConv[sid] || []).filter(
|
|
2339
|
-
(m) => !matchesPinEntry(m,
|
|
2364
|
+
(m) => !matchesPinEntry(m, messageId2, attachmentId || payload.unpinAttachmentId || null)
|
|
2340
2365
|
);
|
|
2341
2366
|
}
|
|
2342
2367
|
const conversation = get().conversations?.find((c) => String(c._id) === String(sid));
|
|
@@ -2351,8 +2376,8 @@ var init_pin_handlers = __esm({
|
|
|
2351
2376
|
pinnedCount = payload.totalCount;
|
|
2352
2377
|
}
|
|
2353
2378
|
const newPendingActions = { ...state.messagePendingActions };
|
|
2354
|
-
if (newPendingActions[
|
|
2355
|
-
delete newPendingActions[
|
|
2379
|
+
if (newPendingActions[messageId2]) {
|
|
2380
|
+
delete newPendingActions[messageId2];
|
|
2356
2381
|
}
|
|
2357
2382
|
return {
|
|
2358
2383
|
lastPinUpdate: payload,
|
|
@@ -2383,13 +2408,13 @@ var init_star_handlers = __esm({
|
|
|
2383
2408
|
init_attachment_helpers();
|
|
2384
2409
|
handleStarUpdate = (set, get, payload) => {
|
|
2385
2410
|
if (payload.starredBy && Array.isArray(payload.starredBy)) {
|
|
2386
|
-
const { messageId:
|
|
2411
|
+
const { messageId: messageId3, attachmentId } = extractMessageData(payload);
|
|
2387
2412
|
const { starredBy } = payload;
|
|
2388
|
-
if (!
|
|
2413
|
+
if (!messageId3) return;
|
|
2389
2414
|
set((state) => {
|
|
2390
|
-
const sid = payload.conversationId || findConversationIdByMessageId(state.messagesByConversation,
|
|
2415
|
+
const sid = payload.conversationId || findConversationIdByMessageId(state.messagesByConversation, messageId3);
|
|
2391
2416
|
const newPendingActions = { ...state.messagePendingActions };
|
|
2392
|
-
const pendingKey = String(
|
|
2417
|
+
const pendingKey = String(messageId3);
|
|
2393
2418
|
if (newPendingActions[pendingKey]) {
|
|
2394
2419
|
delete newPendingActions[pendingKey];
|
|
2395
2420
|
}
|
|
@@ -2399,7 +2424,7 @@ var init_star_handlers = __esm({
|
|
|
2399
2424
|
const loggedUserId = String(get().loggedUserDetails?._id || state.loggedUserDetails?._id || "");
|
|
2400
2425
|
const isStarred2 = starredBy.some((id) => String(id?._id || id) === loggedUserId) || loggedUserId === "" && starredBy.length > 0;
|
|
2401
2426
|
const messages = state.messagesByConversation[sid] || [];
|
|
2402
|
-
const index = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
2427
|
+
const index = messages.findIndex((m) => String(m._id || m.id) === String(messageId3));
|
|
2403
2428
|
let newMessagesByConversation = state.messagesByConversation;
|
|
2404
2429
|
if (index !== -1) {
|
|
2405
2430
|
const newMessages = [...messages];
|
|
@@ -2426,9 +2451,9 @@ var init_star_handlers = __esm({
|
|
|
2426
2451
|
const newStarredByConv = { ...state.starredMessagesByConversation };
|
|
2427
2452
|
const currentStarred = newStarredByConv[sid] || [];
|
|
2428
2453
|
const exists = attachmentId ? currentStarred.some(
|
|
2429
|
-
(m) => m.isAttachment && String(m.messageId) === String(
|
|
2454
|
+
(m) => m.isAttachment && String(m.messageId) === String(messageId3) && String(m.attachmentId) === String(attachmentId)
|
|
2430
2455
|
) : currentStarred.some(
|
|
2431
|
-
(m) => !m.isAttachment && String(m.messageId?._id || m.messageId || m._id || m.id) === String(
|
|
2456
|
+
(m) => !m.isAttachment && String(m.messageId?._id || m.messageId || m._id || m.id) === String(messageId3)
|
|
2432
2457
|
);
|
|
2433
2458
|
const conversation = get().conversations?.find((c) => String(c._id) === String(sid));
|
|
2434
2459
|
const existingCount = state.liveConversationCounts[sid]?.starredCount ?? conversation?.starredCount ?? 0;
|
|
@@ -2436,21 +2461,21 @@ var init_star_handlers = __esm({
|
|
|
2436
2461
|
if (isStarred2 && !exists) {
|
|
2437
2462
|
const fullMessage = attachmentId ? {
|
|
2438
2463
|
_id: attachmentId,
|
|
2439
|
-
messageId:
|
|
2464
|
+
messageId: messageId3,
|
|
2440
2465
|
attachmentId,
|
|
2441
2466
|
isAttachment: true,
|
|
2442
2467
|
attachment: index !== -1 ? newMessagesByConversation[sid][index]?.attachments?.find(
|
|
2443
2468
|
(att) => getAttachmentId(att) === String(attachmentId)
|
|
2444
2469
|
) : payload.attachment,
|
|
2445
2470
|
createdAt: payload.createdAt || (/* @__PURE__ */ new Date()).toISOString()
|
|
2446
|
-
} : index !== -1 ? newMessagesByConversation[sid][index] : { ...payload, _id:
|
|
2471
|
+
} : index !== -1 ? newMessagesByConversation[sid][index] : { ...payload, _id: messageId3 };
|
|
2447
2472
|
newStarredByConv[sid] = [...currentStarred, fullMessage];
|
|
2448
2473
|
starredCount = existingCount + 1;
|
|
2449
2474
|
} else if (!isStarred2 && exists) {
|
|
2450
2475
|
newStarredByConv[sid] = attachmentId ? currentStarred.filter(
|
|
2451
|
-
(m) => !(m.isAttachment && String(m.messageId) === String(
|
|
2476
|
+
(m) => !(m.isAttachment && String(m.messageId) === String(messageId3) && String(m.attachmentId) === String(attachmentId))
|
|
2452
2477
|
) : currentStarred.filter(
|
|
2453
|
-
(m) => String(m.messageId?._id || m.messageId || m._id || m.id) !== String(
|
|
2478
|
+
(m) => String(m.messageId?._id || m.messageId || m._id || m.id) !== String(messageId3)
|
|
2454
2479
|
);
|
|
2455
2480
|
starredCount = Math.max(0, existingCount - 1);
|
|
2456
2481
|
}
|
|
@@ -2476,13 +2501,13 @@ var init_star_handlers = __esm({
|
|
|
2476
2501
|
});
|
|
2477
2502
|
return;
|
|
2478
2503
|
}
|
|
2479
|
-
const { messageId, isStarred, conversationId } = extractMessageData(payload);
|
|
2480
|
-
if (!
|
|
2504
|
+
const { messageId: messageId2, isStarred, conversationId } = extractMessageData(payload);
|
|
2505
|
+
if (!messageId2) return;
|
|
2481
2506
|
set((state) => {
|
|
2482
|
-
const sid = conversationId || findConversationIdByMessageId(state.messagesByConversation,
|
|
2507
|
+
const sid = conversationId || findConversationIdByMessageId(state.messagesByConversation, messageId2);
|
|
2483
2508
|
if (!sid) return { lastStarUpdate: payload };
|
|
2484
2509
|
const messages = state.messagesByConversation[sid] || [];
|
|
2485
|
-
const index = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
2510
|
+
const index = messages.findIndex((m) => String(m._id || m.id) === String(messageId2));
|
|
2486
2511
|
let newMessagesByConversation = state.messagesByConversation;
|
|
2487
2512
|
const msg = index !== -1 ? messages[index] : null;
|
|
2488
2513
|
const wasStarred = msg ? !!msg.isStarred : false;
|
|
@@ -2498,13 +2523,13 @@ var init_star_handlers = __esm({
|
|
|
2498
2523
|
const newStarredByConv = { ...state.starredMessagesByConversation };
|
|
2499
2524
|
if (isStarred) {
|
|
2500
2525
|
const currentStarred = newStarredByConv[sid] || [];
|
|
2501
|
-
if (!currentStarred.some((m) => String(m?._id || m?.id || m.messageId?._id || m.messageId?.id) === String(
|
|
2526
|
+
if (!currentStarred.some((m) => String(m?._id || m?.id || m.messageId?._id || m.messageId?.id) === String(messageId2))) {
|
|
2502
2527
|
const fullMsg = msg ? { ...msg, isStarred: true } : payload;
|
|
2503
2528
|
newStarredByConv[sid] = [...currentStarred, fullMsg];
|
|
2504
2529
|
}
|
|
2505
2530
|
} else {
|
|
2506
2531
|
newStarredByConv[sid] = (newStarredByConv[sid] || []).filter(
|
|
2507
|
-
(m) => String(m?._id || m?.id || m.messageId?._id || m.messageId?.id) !== String(
|
|
2532
|
+
(m) => String(m?._id || m?.id || m.messageId?._id || m.messageId?.id) !== String(messageId2)
|
|
2508
2533
|
);
|
|
2509
2534
|
}
|
|
2510
2535
|
const conversation = get().conversations?.find((c) => String(c._id) === String(sid));
|
|
@@ -2519,7 +2544,7 @@ var init_star_handlers = __esm({
|
|
|
2519
2544
|
starredCount = payload.totalCount;
|
|
2520
2545
|
}
|
|
2521
2546
|
const newPendingActions = { ...state.messagePendingActions };
|
|
2522
|
-
const pendingKey = String(
|
|
2547
|
+
const pendingKey = String(messageId2);
|
|
2523
2548
|
if (newPendingActions[pendingKey]) {
|
|
2524
2549
|
delete newPendingActions[pendingKey];
|
|
2525
2550
|
}
|
|
@@ -2640,15 +2665,15 @@ var init_emit_actions = __esm({
|
|
|
2640
2665
|
exports.socketService.emit("dm_unpin", p);
|
|
2641
2666
|
},
|
|
2642
2667
|
emitDmStar: (p) => {
|
|
2643
|
-
const
|
|
2644
|
-
handleStarUpdate(set, get, { ...p, messageId, isStarred: true });
|
|
2645
|
-
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [
|
|
2668
|
+
const messageId2 = String(p.messageId);
|
|
2669
|
+
handleStarUpdate(set, get, { ...p, messageId: messageId2, isStarred: true });
|
|
2670
|
+
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [messageId2]: ["star"] } }));
|
|
2646
2671
|
exports.socketService.emit("dm_star", p);
|
|
2647
2672
|
},
|
|
2648
2673
|
emitDmUnstar: (p) => {
|
|
2649
|
-
const
|
|
2650
|
-
handleStarUpdate(set, get, { ...p, messageId, isStarred: false });
|
|
2651
|
-
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [
|
|
2674
|
+
const messageId2 = String(p.messageId);
|
|
2675
|
+
handleStarUpdate(set, get, { ...p, messageId: messageId2, isStarred: false });
|
|
2676
|
+
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [messageId2]: ["unstar"] } }));
|
|
2652
2677
|
exports.socketService.emit("dm_unstar", p);
|
|
2653
2678
|
},
|
|
2654
2679
|
emitDmForward: (p) => {
|
|
@@ -2700,15 +2725,15 @@ var init_emit_actions = __esm({
|
|
|
2700
2725
|
exports.socketService.emitGroupUnpin(p);
|
|
2701
2726
|
},
|
|
2702
2727
|
emitGroupStar: (p) => {
|
|
2703
|
-
const
|
|
2704
|
-
handleStarUpdate(set, get, { ...p, messageId, isStarred: true });
|
|
2705
|
-
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [
|
|
2728
|
+
const messageId2 = String(p.messageId);
|
|
2729
|
+
handleStarUpdate(set, get, { ...p, messageId: messageId2, isStarred: true });
|
|
2730
|
+
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [messageId2]: ["star"] } }));
|
|
2706
2731
|
exports.socketService.emitGroupStar(p);
|
|
2707
2732
|
},
|
|
2708
2733
|
emitGroupUnstar: (p) => {
|
|
2709
|
-
const
|
|
2710
|
-
handleStarUpdate(set, get, { ...p, messageId, isStarred: false });
|
|
2711
|
-
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [
|
|
2734
|
+
const messageId2 = String(p.messageId);
|
|
2735
|
+
handleStarUpdate(set, get, { ...p, messageId: messageId2, isStarred: false });
|
|
2736
|
+
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [messageId2]: ["unstar"] } }));
|
|
2712
2737
|
exports.socketService.emitGroupUnstar(p);
|
|
2713
2738
|
},
|
|
2714
2739
|
emitGroupForward: (p) => {
|
|
@@ -2727,8 +2752,8 @@ var init_emit_actions = __esm({
|
|
|
2727
2752
|
...p.attachmentId ? { attachmentId: String(p.attachmentId) } : {}
|
|
2728
2753
|
});
|
|
2729
2754
|
},
|
|
2730
|
-
clearForwardPending: (
|
|
2731
|
-
clearForwardPendingActions(set,
|
|
2755
|
+
clearForwardPending: (messageId2) => {
|
|
2756
|
+
clearForwardPendingActions(set, messageId2);
|
|
2732
2757
|
},
|
|
2733
2758
|
emitConversationUpdate: (p) => exports.socketService.emitConversationUpdate(p),
|
|
2734
2759
|
emitGroupLeave: (p) => exports.socketService.emitGroupLeave(p),
|
|
@@ -2753,7 +2778,7 @@ var init_message_handlers = __esm({
|
|
|
2753
2778
|
get().conversations,
|
|
2754
2779
|
loggedUserId
|
|
2755
2780
|
);
|
|
2756
|
-
const { messageId } = extractMessageData(lastDM);
|
|
2781
|
+
const { messageId: messageId2 } = extractMessageData(lastDM);
|
|
2757
2782
|
const tempId = lastDM.tempId;
|
|
2758
2783
|
const isFromSelf = loggedUserDetails && String(lastDM.sender?._id || lastDM.sender) === String(loggedUserDetails._id);
|
|
2759
2784
|
const activeConversationId = get().activeConversationId;
|
|
@@ -2763,14 +2788,14 @@ var init_message_handlers = __esm({
|
|
|
2763
2788
|
const newPendingActions = { ...state.messagePendingActions };
|
|
2764
2789
|
if (conversationId) {
|
|
2765
2790
|
const current = nextMessagesByConversation[conversationId] || [];
|
|
2766
|
-
let matchedId =
|
|
2791
|
+
let matchedId = messageId2;
|
|
2767
2792
|
if (tempId && state.messagePendingActions[tempId]) {
|
|
2768
2793
|
matchedId = tempId;
|
|
2769
2794
|
}
|
|
2770
|
-
const exists = current.some((m) => String(m._id || m.id) === String(
|
|
2795
|
+
const exists = current.some((m) => String(m._id || m.id) === String(messageId2));
|
|
2771
2796
|
if (matchedId && matchedId === tempId) {
|
|
2772
2797
|
nextMessagesByConversation[conversationId] = current.map(
|
|
2773
|
-
(m) => String(m.id || m._id) === String(matchedId) ? { ...m, _id:
|
|
2798
|
+
(m) => String(m.id || m._id) === String(matchedId) ? { ...m, _id: messageId2, id: messageId2, status: messageWithStatus.status } : m
|
|
2774
2799
|
);
|
|
2775
2800
|
delete newPendingActions[matchedId];
|
|
2776
2801
|
} else if (!exists) {
|
|
@@ -2803,8 +2828,7 @@ var init_message_handlers = __esm({
|
|
|
2803
2828
|
conversationType: lastDM.conversationType || "individual",
|
|
2804
2829
|
isGroup: false,
|
|
2805
2830
|
...shouldIncludeParticipants ? { participants: participantSeed } : {},
|
|
2806
|
-
groupName: lastDM.groupName,
|
|
2807
|
-
name: lastDM.groupName,
|
|
2831
|
+
...lastDM.groupName ? { groupName: lastDM.groupName, name: lastDM.groupName } : {},
|
|
2808
2832
|
owner: existingConv?.owner ?? lastDM.owner
|
|
2809
2833
|
},
|
|
2810
2834
|
{
|
|
@@ -2826,27 +2850,27 @@ var init_message_handlers = __esm({
|
|
|
2826
2850
|
}
|
|
2827
2851
|
};
|
|
2828
2852
|
handleEditDM = (set, get, payload) => {
|
|
2829
|
-
const { messageId, content, conversationId, attachmentId, caption } = extractMessageData(payload);
|
|
2830
|
-
if (!
|
|
2853
|
+
const { messageId: messageId2, content, conversationId, attachmentId, caption } = extractMessageData(payload);
|
|
2854
|
+
if (!messageId2) return;
|
|
2831
2855
|
const captionText = caption ?? content ?? "";
|
|
2832
2856
|
set((state) => {
|
|
2833
2857
|
let searchConversationId = conversationId;
|
|
2834
2858
|
if (!searchConversationId) {
|
|
2835
|
-
searchConversationId = findConversationIdByMessageId(state.messagesByConversation,
|
|
2859
|
+
searchConversationId = findConversationIdByMessageId(state.messagesByConversation, messageId2);
|
|
2836
2860
|
}
|
|
2837
2861
|
if (!searchConversationId) {
|
|
2838
2862
|
searchConversationId = state.conversations.find(
|
|
2839
|
-
(c) => String(c.lastMessage?._id || c.lastMessage?.id) === String(
|
|
2863
|
+
(c) => String(c.lastMessage?._id || c.lastMessage?.id) === String(messageId2)
|
|
2840
2864
|
)?._id;
|
|
2841
2865
|
}
|
|
2842
|
-
const normalizedEditPayload = { ...payload, messageId, content, conversationId: searchConversationId, _v: Date.now() };
|
|
2866
|
+
const normalizedEditPayload = { ...payload, messageId: messageId2, content, conversationId: searchConversationId, _v: Date.now() };
|
|
2843
2867
|
const newPendingActions = { ...state.messagePendingActions };
|
|
2844
|
-
if (newPendingActions[
|
|
2845
|
-
delete newPendingActions[
|
|
2868
|
+
if (newPendingActions[messageId2]) {
|
|
2869
|
+
delete newPendingActions[messageId2];
|
|
2846
2870
|
}
|
|
2847
2871
|
if (searchConversationId) {
|
|
2848
2872
|
const messages = state.messagesByConversation[searchConversationId] || [];
|
|
2849
|
-
const index = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
2873
|
+
const index = messages.findIndex((m) => String(m._id || m.id) === String(messageId2));
|
|
2850
2874
|
if (index !== -1) {
|
|
2851
2875
|
const newMessages = [...messages];
|
|
2852
2876
|
if (attachmentId) {
|
|
@@ -2872,15 +2896,15 @@ var init_message_handlers = __esm({
|
|
|
2872
2896
|
});
|
|
2873
2897
|
};
|
|
2874
2898
|
handleDeleteDM = (set, get, payload, type) => {
|
|
2875
|
-
const { messageId, conversationId, attachmentId } = extractMessageData(payload);
|
|
2876
|
-
if (!
|
|
2899
|
+
const { messageId: messageId2, conversationId, attachmentId } = extractMessageData(payload);
|
|
2900
|
+
if (!messageId2) return;
|
|
2877
2901
|
set((state) => {
|
|
2878
|
-
const searchConversationId = conversationId || findConversationIdByMessageId(state.messagesByConversation,
|
|
2902
|
+
const searchConversationId = conversationId || findConversationIdByMessageId(state.messagesByConversation, messageId2);
|
|
2879
2903
|
const messageTombstoned = payload.messageTombstoned === true;
|
|
2880
2904
|
let updatedConversations = state.conversations;
|
|
2881
2905
|
if (searchConversationId && !attachmentId) {
|
|
2882
2906
|
updatedConversations = state.conversations.map((c) => {
|
|
2883
|
-
if (String(c._id) === String(searchConversationId) && String(c.lastMessage?._id || c.lastMessage?.id) === String(
|
|
2907
|
+
if (String(c._id) === String(searchConversationId) && String(c.lastMessage?._id || c.lastMessage?.id) === String(messageId2)) {
|
|
2884
2908
|
return { ...c, lastMessage: type === "me" ? { ...c.lastMessage, content: "" } : { ...c.lastMessage, isDeletedForEveryone: true, content: "This message has been deleted" } };
|
|
2885
2909
|
}
|
|
2886
2910
|
return c;
|
|
@@ -2891,7 +2915,7 @@ var init_message_handlers = __esm({
|
|
|
2891
2915
|
if (searchConversationId) {
|
|
2892
2916
|
if (attachmentId) {
|
|
2893
2917
|
const updatedMessages = messages.map((m) => {
|
|
2894
|
-
if (String(m._id || m.id) !== String(
|
|
2918
|
+
if (String(m._id || m.id) !== String(messageId2)) return m;
|
|
2895
2919
|
if (messageTombstoned || type === "everyone" && payload.content) {
|
|
2896
2920
|
return {
|
|
2897
2921
|
...m,
|
|
@@ -2930,22 +2954,22 @@ var init_message_handlers = __esm({
|
|
|
2930
2954
|
[searchConversationId]: updatedMessages
|
|
2931
2955
|
};
|
|
2932
2956
|
} else if (type === "me") {
|
|
2933
|
-
nextMessagesByConversation = { ...state.messagesByConversation, [searchConversationId]: messages.filter((m) => String(m._id || m.id) !== String(
|
|
2957
|
+
nextMessagesByConversation = { ...state.messagesByConversation, [searchConversationId]: messages.filter((m) => String(m._id || m.id) !== String(messageId2)) };
|
|
2934
2958
|
} else {
|
|
2935
2959
|
nextMessagesByConversation = {
|
|
2936
2960
|
...state.messagesByConversation,
|
|
2937
|
-
[searchConversationId]: messages.map((m) => String(m._id || m.id) === String(
|
|
2961
|
+
[searchConversationId]: messages.map((m) => String(m._id || m.id) === String(messageId2) ? { ...m, isDeletedForEveryone: true, content: "" } : m)
|
|
2938
2962
|
};
|
|
2939
2963
|
}
|
|
2940
2964
|
}
|
|
2941
2965
|
const newPendingActions = { ...state.messagePendingActions };
|
|
2942
|
-
if (newPendingActions[
|
|
2943
|
-
delete newPendingActions[
|
|
2966
|
+
if (newPendingActions[messageId2]) {
|
|
2967
|
+
delete newPendingActions[messageId2];
|
|
2944
2968
|
}
|
|
2945
|
-
const shouldMarkWholeMessageDeleted = type === "me" && !attachmentId && !state.deletedForMeIds.includes(
|
|
2969
|
+
const shouldMarkWholeMessageDeleted = type === "me" && !attachmentId && !state.deletedForMeIds.includes(messageId2);
|
|
2946
2970
|
return {
|
|
2947
2971
|
lastDeleteDM: { ...payload, deleteType: type },
|
|
2948
|
-
deletedForMeIds: shouldMarkWholeMessageDeleted ? [...state.deletedForMeIds,
|
|
2972
|
+
deletedForMeIds: shouldMarkWholeMessageDeleted ? [...state.deletedForMeIds, messageId2] : state.deletedForMeIds,
|
|
2949
2973
|
messagesByConversation: nextMessagesByConversation,
|
|
2950
2974
|
conversations: updatedConversations,
|
|
2951
2975
|
messagePendingActions: newPendingActions
|
|
@@ -3019,15 +3043,15 @@ var init_dm_actions = __esm({
|
|
|
3019
3043
|
},
|
|
3020
3044
|
receivedStatusUpdate: (payload) => {
|
|
3021
3045
|
const data = extractMessageData(payload);
|
|
3022
|
-
const { messageId, status } = data;
|
|
3046
|
+
const { messageId: messageId2, status } = data;
|
|
3023
3047
|
let { conversationId } = data;
|
|
3024
|
-
if (!
|
|
3048
|
+
if (!messageId2 || !status) return;
|
|
3025
3049
|
set({ lastStatusUpdate: payload });
|
|
3026
3050
|
if (!conversationId) {
|
|
3027
|
-
conversationId = findConversationIdByMessageId(get().messagesByConversation,
|
|
3051
|
+
conversationId = findConversationIdByMessageId(get().messagesByConversation, messageId2) || findConversationIdByLastMessageId(get().conversations, messageId2) || void 0;
|
|
3028
3052
|
}
|
|
3029
3053
|
set((state) => ({
|
|
3030
|
-
...applyMessageStatusToStore(state, String(
|
|
3054
|
+
...applyMessageStatusToStore(state, String(messageId2), status, conversationId)
|
|
3031
3055
|
}));
|
|
3032
3056
|
},
|
|
3033
3057
|
receivedDMMarkRead: (payload) => {
|
|
@@ -3084,7 +3108,7 @@ var init_group_handlers = __esm({
|
|
|
3084
3108
|
get().conversations,
|
|
3085
3109
|
loggedUserId
|
|
3086
3110
|
);
|
|
3087
|
-
const { messageId } = extractMessageData(lastDM);
|
|
3111
|
+
const { messageId: messageId2 } = extractMessageData(lastDM);
|
|
3088
3112
|
const tempId = lastDM.tempId;
|
|
3089
3113
|
const activeConversationId = get().activeConversationId;
|
|
3090
3114
|
const isOpenConversation = conversationId && String(conversationId) === String(activeConversationId);
|
|
@@ -3121,23 +3145,23 @@ var init_group_handlers = __esm({
|
|
|
3121
3145
|
);
|
|
3122
3146
|
if (optimisticMsg) matchedTempId = optimisticMsg.id;
|
|
3123
3147
|
}
|
|
3124
|
-
const messageExists = current.some((m) => String(m._id || m.id) === String(
|
|
3148
|
+
const messageExists = current.some((m) => String(m._id || m.id) === String(messageId2));
|
|
3125
3149
|
if (!messageExists) {
|
|
3126
3150
|
nextMessagesByConversation[conversationId] = [...current, {
|
|
3127
3151
|
...lastDM,
|
|
3128
|
-
_id:
|
|
3129
|
-
id:
|
|
3152
|
+
_id: messageId2,
|
|
3153
|
+
id: messageId2,
|
|
3130
3154
|
status: lastDM.status || "sent"
|
|
3131
3155
|
}];
|
|
3132
3156
|
} else {
|
|
3133
3157
|
nextMessagesByConversation[conversationId] = current.map(
|
|
3134
|
-
(m) => String(m._id || m.id) === String(
|
|
3158
|
+
(m) => String(m._id || m.id) === String(messageId2) ? { ...m, status: lastDM.status || "sent" } : m
|
|
3135
3159
|
);
|
|
3136
3160
|
}
|
|
3137
3161
|
if (matchedTempId) {
|
|
3138
3162
|
delete newPendingActions[matchedTempId];
|
|
3139
3163
|
nextMessagesByConversation[conversationId] = nextMessagesByConversation[conversationId].map(
|
|
3140
|
-
(m) => String(m.id || m._id) === String(matchedTempId) ? { ...m, _id:
|
|
3164
|
+
(m) => String(m.id || m._id) === String(matchedTempId) ? { ...m, _id: messageId2, id: messageId2, status: lastDM.status || "sent" } : m
|
|
3141
3165
|
);
|
|
3142
3166
|
}
|
|
3143
3167
|
}
|
|
@@ -3147,8 +3171,10 @@ var init_group_handlers = __esm({
|
|
|
3147
3171
|
_id: conversationId,
|
|
3148
3172
|
conversationType: "group",
|
|
3149
3173
|
isGroup: true,
|
|
3150
|
-
groupName
|
|
3151
|
-
|
|
3174
|
+
...lastDM.groupName || lastDM.name ? {
|
|
3175
|
+
groupName: lastDM.groupName || lastDM.name,
|
|
3176
|
+
name: lastDM.groupName || lastDM.name
|
|
3177
|
+
} : {},
|
|
3152
3178
|
participants: buildParticipantsFromMessagePayload(lastDM, loggedUserId)
|
|
3153
3179
|
},
|
|
3154
3180
|
{
|
|
@@ -3186,8 +3212,10 @@ var init_group_handlers = __esm({
|
|
|
3186
3212
|
_id: conversationId,
|
|
3187
3213
|
conversationType: "group",
|
|
3188
3214
|
isGroup: true,
|
|
3189
|
-
groupName
|
|
3190
|
-
|
|
3215
|
+
...lastDM.groupName || lastDM.name ? {
|
|
3216
|
+
groupName: lastDM.groupName || lastDM.name,
|
|
3217
|
+
name: lastDM.groupName || lastDM.name
|
|
3218
|
+
} : {},
|
|
3191
3219
|
participants: buildParticipantsFromMessagePayload(lastDM, loggedUserId)
|
|
3192
3220
|
},
|
|
3193
3221
|
{
|
|
@@ -3206,10 +3234,10 @@ var init_group_handlers = __esm({
|
|
|
3206
3234
|
(c) => String(c._id) === String(conversationId)
|
|
3207
3235
|
);
|
|
3208
3236
|
const isGroupChat = isGroupConversation(targetConv);
|
|
3209
|
-
if (loggedUserDetails?._id &&
|
|
3237
|
+
if (loggedUserDetails?._id && messageId2 && isGroupChat) {
|
|
3210
3238
|
get().emitGroupMessageDelivered({
|
|
3211
3239
|
conversationId,
|
|
3212
|
-
messageId,
|
|
3240
|
+
messageId: messageId2,
|
|
3213
3241
|
userId: loggedUserDetails._id
|
|
3214
3242
|
});
|
|
3215
3243
|
}
|
|
@@ -3287,15 +3315,15 @@ var init_group_actions2 = __esm({
|
|
|
3287
3315
|
receivedGroupStatusUpdate: (payload) => {
|
|
3288
3316
|
const data = extractMessageData(payload);
|
|
3289
3317
|
let { conversationId } = data;
|
|
3290
|
-
const { messageId, status } = data;
|
|
3318
|
+
const { messageId: messageId2, status } = data;
|
|
3291
3319
|
set({ lastStatusUpdate: payload });
|
|
3292
3320
|
if (!status) return;
|
|
3293
|
-
if (
|
|
3321
|
+
if (messageId2) {
|
|
3294
3322
|
if (!conversationId) {
|
|
3295
|
-
conversationId = findConversationIdByMessageId(get().messagesByConversation,
|
|
3323
|
+
conversationId = findConversationIdByMessageId(get().messagesByConversation, messageId2) || findConversationIdByLastMessageId(get().conversations, messageId2) || void 0;
|
|
3296
3324
|
}
|
|
3297
3325
|
set((state) => ({
|
|
3298
|
-
...applyMessageStatusToStore(state, String(
|
|
3326
|
+
...applyMessageStatusToStore(state, String(messageId2), status, conversationId)
|
|
3299
3327
|
}));
|
|
3300
3328
|
return;
|
|
3301
3329
|
}
|
|
@@ -3511,7 +3539,7 @@ var init_receive = __esm({
|
|
|
3511
3539
|
};
|
|
3512
3540
|
});
|
|
3513
3541
|
},
|
|
3514
|
-
markDeletedForMe: (
|
|
3542
|
+
markDeletedForMe: (messageId2) => set((state) => ({ deletedForMeIds: [...state.deletedForMeIds, messageId2] }))
|
|
3515
3543
|
});
|
|
3516
3544
|
createReceiveActions = (set, get) => ({
|
|
3517
3545
|
...createDmReceiveActions(set, get),
|
|
@@ -3536,13 +3564,13 @@ var init_search_actions = __esm({
|
|
|
3536
3564
|
init_api_service();
|
|
3537
3565
|
init_store_helpers();
|
|
3538
3566
|
createSearchActions = (set, _get) => ({
|
|
3539
|
-
fetchSearchMessageContext: async (
|
|
3567
|
+
fetchSearchMessageContext: async (messageId2, options) => {
|
|
3540
3568
|
const searchMode = options?.searchMode !== false;
|
|
3541
|
-
set({ isSearchActive: searchMode, searchedMessageId:
|
|
3569
|
+
set({ isSearchActive: searchMode, searchedMessageId: messageId2, isFetchingMessages: true });
|
|
3542
3570
|
try {
|
|
3543
|
-
const response = await searchMessagesContext(
|
|
3571
|
+
const response = await searchMessagesContext(messageId2);
|
|
3544
3572
|
const data = response.data?.list || response.data?.messages || response.messages || response.data || [];
|
|
3545
|
-
const highlightId = response.data?.highlightMessageId ||
|
|
3573
|
+
const highlightId = response.data?.highlightMessageId || messageId2;
|
|
3546
3574
|
if (data.length > 0) {
|
|
3547
3575
|
const conversationId = data[0].conversationId;
|
|
3548
3576
|
if (conversationId) {
|
|
@@ -3571,7 +3599,7 @@ var init_search_actions = __esm({
|
|
|
3571
3599
|
}
|
|
3572
3600
|
},
|
|
3573
3601
|
setSearchActive: (active) => set({ isSearchActive: active }),
|
|
3574
|
-
setSearchedMessageId: (
|
|
3602
|
+
setSearchedMessageId: (messageId2) => set({ searchedMessageId: messageId2 })
|
|
3575
3603
|
});
|
|
3576
3604
|
}
|
|
3577
3605
|
});
|
|
@@ -3938,6 +3966,7 @@ var buildIncomingMessageFromDM = (lastDM, loggedUserId, conversations) => {
|
|
|
3938
3966
|
content: lastDM.content || lastDM.message?.content || "",
|
|
3939
3967
|
sender: lastDM.sender?.name || lastDM.fromUserId || (isMe ? "Me" : "User"),
|
|
3940
3968
|
senderId: String(lastDM.sender?._id || lastDM.sender || lastDM.fromUserId || ""),
|
|
3969
|
+
senderImage: lastDM.sender?.image,
|
|
3941
3970
|
timestamp: lastDM.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
3942
3971
|
isOwnMessage: isMe,
|
|
3943
3972
|
channelId,
|
|
@@ -4095,9 +4124,9 @@ var syncLocalMessagesOnPinUpdate = (prev, lastPinUpdate) => {
|
|
|
4095
4124
|
return next;
|
|
4096
4125
|
};
|
|
4097
4126
|
var syncLocalMessagesOnStarUpdate = (prev, lastStarUpdate, loggedUserId) => {
|
|
4098
|
-
const
|
|
4099
|
-
if (!
|
|
4100
|
-
const mid = String(
|
|
4127
|
+
const messageId2 = lastStarUpdate.messageId || lastStarUpdate._id;
|
|
4128
|
+
if (!messageId2) return null;
|
|
4129
|
+
const mid = String(messageId2);
|
|
4101
4130
|
let isStarred;
|
|
4102
4131
|
if (typeof lastStarUpdate.isStarred === "boolean") {
|
|
4103
4132
|
isStarred = lastStarUpdate.isStarred;
|
|
@@ -4116,9 +4145,9 @@ var syncLocalMessagesOnStarUpdate = (prev, lastStarUpdate, loggedUserId) => {
|
|
|
4116
4145
|
return next;
|
|
4117
4146
|
};
|
|
4118
4147
|
var syncLocalMessagesOnReactionUpdate = (prev, lastReactionUpdate, messagesByConversation) => {
|
|
4119
|
-
const
|
|
4120
|
-
if (!
|
|
4121
|
-
const mid = String(
|
|
4148
|
+
const messageId2 = lastReactionUpdate.messageId || lastReactionUpdate._id;
|
|
4149
|
+
if (!messageId2) return prev;
|
|
4150
|
+
const mid = String(messageId2);
|
|
4122
4151
|
let storeReactions;
|
|
4123
4152
|
for (const msgs of Object.values(messagesByConversation)) {
|
|
4124
4153
|
const found = msgs.find((m) => String(m._id || m.id) === mid);
|
|
@@ -4169,7 +4198,7 @@ var syncLocalMessagesOnReactionUpdate = (prev, lastReactionUpdate, messagesByCon
|
|
|
4169
4198
|
return changed ? next : prev;
|
|
4170
4199
|
};
|
|
4171
4200
|
var syncLocalMessagesOnDelete = (prev, lastDeleteDM) => {
|
|
4172
|
-
const
|
|
4201
|
+
const messageId2 = lastDeleteDM.messageId || lastDeleteDM._id;
|
|
4173
4202
|
const deleteType = lastDeleteDM.deleteType || "everyone";
|
|
4174
4203
|
const attachmentId = lastDeleteDM.attachmentId ? String(lastDeleteDM.attachmentId) : null;
|
|
4175
4204
|
const messageTombstoned = lastDeleteDM.messageTombstoned === true;
|
|
@@ -4177,7 +4206,7 @@ var syncLocalMessagesOnDelete = (prev, lastDeleteDM) => {
|
|
|
4177
4206
|
Object.keys(next).forEach((channelId) => {
|
|
4178
4207
|
if (attachmentId) {
|
|
4179
4208
|
next[channelId] = next[channelId].map((message) => {
|
|
4180
|
-
if (String(message._id || message.id) !== String(
|
|
4209
|
+
if (String(message._id || message.id) !== String(messageId2)) {
|
|
4181
4210
|
return message;
|
|
4182
4211
|
}
|
|
4183
4212
|
return applyLocalAttachmentDelete(
|
|
@@ -4191,26 +4220,26 @@ var syncLocalMessagesOnDelete = (prev, lastDeleteDM) => {
|
|
|
4191
4220
|
}
|
|
4192
4221
|
if (deleteType === "me") {
|
|
4193
4222
|
next[channelId] = next[channelId].filter(
|
|
4194
|
-
(m) => String(m._id || m.id) !== String(
|
|
4223
|
+
(m) => String(m._id || m.id) !== String(messageId2)
|
|
4195
4224
|
);
|
|
4196
4225
|
} else {
|
|
4197
4226
|
next[channelId] = next[channelId].map(
|
|
4198
|
-
(m) => String(m._id || m.id) === String(
|
|
4227
|
+
(m) => String(m._id || m.id) === String(messageId2) ? { ...m, isDeletedForEveryone: true } : m
|
|
4199
4228
|
);
|
|
4200
4229
|
}
|
|
4201
4230
|
});
|
|
4202
4231
|
return next;
|
|
4203
4232
|
};
|
|
4204
4233
|
var syncLocalMessagesOnEdit = (prev, lastEditDM) => {
|
|
4205
|
-
const
|
|
4234
|
+
const messageId2 = lastEditDM.messageId || lastEditDM._id;
|
|
4206
4235
|
const content = lastEditDM.content;
|
|
4207
4236
|
const attachmentId = lastEditDM.attachmentId ? String(lastEditDM.attachmentId) : null;
|
|
4208
4237
|
const caption = lastEditDM.caption ?? content;
|
|
4209
|
-
if (!
|
|
4238
|
+
if (!messageId2) return null;
|
|
4210
4239
|
const next = { ...prev };
|
|
4211
4240
|
Object.keys(next).forEach((channelId) => {
|
|
4212
4241
|
const messages = next[channelId];
|
|
4213
|
-
const index = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
4242
|
+
const index = messages.findIndex((m) => String(m._id || m.id) === String(messageId2));
|
|
4214
4243
|
if (index !== -1) {
|
|
4215
4244
|
const updated = [...messages];
|
|
4216
4245
|
const current = updated[index];
|
|
@@ -4480,7 +4509,7 @@ var Chat = ({
|
|
|
4480
4509
|
const status = exports.useChatStore((s) => s.status);
|
|
4481
4510
|
const error = exports.useChatStore((s) => s.error);
|
|
4482
4511
|
useChatSync();
|
|
4483
|
-
|
|
4512
|
+
React2__namespace.default.useEffect(() => {
|
|
4484
4513
|
const clientId = client?.id;
|
|
4485
4514
|
const initializeChat = async () => {
|
|
4486
4515
|
if (!clientId || !loggedUserDetails) return;
|
|
@@ -4569,28 +4598,28 @@ var Chat = ({
|
|
|
4569
4598
|
queryParamApis: queryParamApis ?? ["get"],
|
|
4570
4599
|
queryParamsByApi: queryParamsByApi ?? {}
|
|
4571
4600
|
});
|
|
4572
|
-
|
|
4601
|
+
React2__namespace.default.useEffect(() => {
|
|
4573
4602
|
exports.setChatQueryParams(queryParams);
|
|
4574
4603
|
exports.setChatQueryParamApis(queryParamApis);
|
|
4575
4604
|
exports.setChatQueryParamsByApi(queryParamsByApi);
|
|
4576
4605
|
}, [queryConfigKey]);
|
|
4577
|
-
|
|
4606
|
+
React2__namespace.default.useEffect(() => {
|
|
4578
4607
|
if (lastDM && onMessageReceived) {
|
|
4579
4608
|
onMessageReceived(lastDM);
|
|
4580
4609
|
}
|
|
4581
4610
|
}, [lastDM, onMessageReceived]);
|
|
4582
|
-
|
|
4611
|
+
React2__namespace.default.useEffect(() => {
|
|
4583
4612
|
if (status === "connected" && onSocketConnected) {
|
|
4584
4613
|
const socketId = exports.useChatStore.getState().socketId;
|
|
4585
4614
|
if (socketId) onSocketConnected(socketId);
|
|
4586
4615
|
}
|
|
4587
4616
|
}, [status, onSocketConnected]);
|
|
4588
|
-
|
|
4617
|
+
React2__namespace.default.useEffect(() => {
|
|
4589
4618
|
if (status === "error" && error && onSocketError) {
|
|
4590
4619
|
onSocketError(error);
|
|
4591
4620
|
}
|
|
4592
4621
|
}, [status, error, onSocketError]);
|
|
4593
|
-
const contextValue =
|
|
4622
|
+
const contextValue = React2__namespace.default.useMemo(
|
|
4594
4623
|
() => ({
|
|
4595
4624
|
onSendMessage,
|
|
4596
4625
|
client,
|
|
@@ -4610,7 +4639,7 @@ var Chat = ({
|
|
|
4610
4639
|
messagesData
|
|
4611
4640
|
]
|
|
4612
4641
|
);
|
|
4613
|
-
const customization =
|
|
4642
|
+
const customization = React2__namespace.default.useMemo(
|
|
4614
4643
|
() => ({
|
|
4615
4644
|
components: uiConfig.components,
|
|
4616
4645
|
classNames: uiConfig.classNames,
|
|
@@ -6705,20 +6734,35 @@ init_chat_constants();
|
|
|
6705
6734
|
// src/chat/lib/last-message-preview.ts
|
|
6706
6735
|
init_store_helpers();
|
|
6707
6736
|
|
|
6708
|
-
// src/chat/lib/
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6737
|
+
// src/chat/lib/attachment-preview-labels.ts
|
|
6738
|
+
function getAttachmentTypePreviewLabel(type) {
|
|
6739
|
+
switch (String(type || "").toLowerCase()) {
|
|
6740
|
+
case "image":
|
|
6741
|
+
return "Photo";
|
|
6742
|
+
case "video":
|
|
6743
|
+
return "Video";
|
|
6744
|
+
case "audio":
|
|
6745
|
+
return "Audio";
|
|
6746
|
+
case "file":
|
|
6747
|
+
case "document":
|
|
6748
|
+
case "spreadsheet":
|
|
6749
|
+
return "Attachment";
|
|
6750
|
+
default:
|
|
6751
|
+
return "Attachment";
|
|
6717
6752
|
}
|
|
6718
|
-
|
|
6719
|
-
|
|
6753
|
+
}
|
|
6754
|
+
function getAttachmentCountPreviewLabel(type, count) {
|
|
6755
|
+
if (count <= 1) return getAttachmentTypePreviewLabel(type);
|
|
6756
|
+
switch (String(type).toLowerCase()) {
|
|
6757
|
+
case "image":
|
|
6758
|
+
return `${count} photos`;
|
|
6759
|
+
case "video":
|
|
6760
|
+
return `${count} videos`;
|
|
6761
|
+
case "audio":
|
|
6762
|
+
return `${count} audio files`;
|
|
6763
|
+
default:
|
|
6764
|
+
return `${count} attachments`;
|
|
6720
6765
|
}
|
|
6721
|
-
return name.trim() || trimmed;
|
|
6722
6766
|
}
|
|
6723
6767
|
|
|
6724
6768
|
// src/chat/lib/last-message-preview.ts
|
|
@@ -6726,21 +6770,30 @@ function getAttachmentOnlyPreviewText(attachments) {
|
|
|
6726
6770
|
const images = attachments.filter((att2) => att2.type === "image" && att2.url);
|
|
6727
6771
|
const videos = attachments.filter((att2) => att2.type === "video" && att2.url);
|
|
6728
6772
|
const audios = attachments.filter((att2) => att2.type === "audio" && att2.url);
|
|
6729
|
-
|
|
6773
|
+
const files = attachments.filter(
|
|
6774
|
+
(att2) => att2.url && !["image", "video", "audio"].includes(att2.type)
|
|
6775
|
+
);
|
|
6776
|
+
if (images.length > 1) return getAttachmentCountPreviewLabel("image", images.length);
|
|
6730
6777
|
if (images.length === 1) {
|
|
6731
|
-
return images[0].caption?.trim() || "
|
|
6778
|
+
return images[0].caption?.trim() || getAttachmentTypePreviewLabel("image");
|
|
6732
6779
|
}
|
|
6733
|
-
if (videos.length > 1) return
|
|
6780
|
+
if (videos.length > 1) return getAttachmentCountPreviewLabel("video", videos.length);
|
|
6734
6781
|
if (videos.length === 1) {
|
|
6735
|
-
return videos[0].caption?.trim() || "
|
|
6782
|
+
return videos[0].caption?.trim() || getAttachmentTypePreviewLabel("video");
|
|
6736
6783
|
}
|
|
6737
|
-
if (audios.length > 1) return
|
|
6784
|
+
if (audios.length > 1) return getAttachmentCountPreviewLabel("audio", audios.length);
|
|
6738
6785
|
if (audios.length === 1) {
|
|
6739
|
-
return audios[0].caption?.trim() || "
|
|
6786
|
+
return audios[0].caption?.trim() || getAttachmentTypePreviewLabel("audio");
|
|
6787
|
+
}
|
|
6788
|
+
if (files.length > 1) return getAttachmentCountPreviewLabel("file", files.length);
|
|
6789
|
+
if (files.length === 1) {
|
|
6790
|
+
return files[0].caption?.trim() || getAttachmentTypePreviewLabel(files[0].type);
|
|
6791
|
+
}
|
|
6792
|
+
if (attachments.length > 1) {
|
|
6793
|
+
return getAttachmentCountPreviewLabel("file", attachments.length);
|
|
6740
6794
|
}
|
|
6741
|
-
if (attachments.length > 1) return `${attachments.length} files`;
|
|
6742
6795
|
const att = attachments[0];
|
|
6743
|
-
return att
|
|
6796
|
+
return att?.caption?.trim() || getAttachmentTypePreviewLabel(att?.type);
|
|
6744
6797
|
}
|
|
6745
6798
|
function getLastMessageSidebarPreview(message) {
|
|
6746
6799
|
const content = String(message?.content || "").trim();
|
|
@@ -6754,6 +6807,10 @@ function getLastMessageSidebarPreview(message) {
|
|
|
6754
6807
|
if (attachments.length > 0) {
|
|
6755
6808
|
return getAttachmentOnlyPreviewText(attachments);
|
|
6756
6809
|
}
|
|
6810
|
+
const messageType = String(message?.type || "").toLowerCase();
|
|
6811
|
+
if (messageType && messageType !== "text") {
|
|
6812
|
+
return getAttachmentTypePreviewLabel(messageType);
|
|
6813
|
+
}
|
|
6757
6814
|
return "No messages yet";
|
|
6758
6815
|
}
|
|
6759
6816
|
function getMessagePreviewText(message, fallback = "Message") {
|
|
@@ -6765,6 +6822,10 @@ function getMessagePreviewText(message, fallback = "Message") {
|
|
|
6765
6822
|
if (attachments.length > 0) {
|
|
6766
6823
|
return getAttachmentOnlyPreviewText(attachments);
|
|
6767
6824
|
}
|
|
6825
|
+
const messageType = String(message?.type || "").toLowerCase();
|
|
6826
|
+
if (messageType && messageType !== "text") {
|
|
6827
|
+
return getAttachmentTypePreviewLabel(messageType);
|
|
6828
|
+
}
|
|
6768
6829
|
return fallback;
|
|
6769
6830
|
}
|
|
6770
6831
|
|
|
@@ -7406,7 +7467,7 @@ function highlightSearchMatch(text, query) {
|
|
|
7406
7467
|
children: part
|
|
7407
7468
|
},
|
|
7408
7469
|
`${part}-${index}`
|
|
7409
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
7470
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(React2__namespace.default.Fragment, { children: part }, `${part}-${index}`)
|
|
7410
7471
|
);
|
|
7411
7472
|
}
|
|
7412
7473
|
function getMessagePreview(message) {
|
|
@@ -7821,11 +7882,11 @@ function buildAttachmentSummary(attachments) {
|
|
|
7821
7882
|
else fileCount += 1;
|
|
7822
7883
|
}
|
|
7823
7884
|
const parts = [];
|
|
7824
|
-
if (imageCount) parts.push(
|
|
7825
|
-
if (videoCount) parts.push(
|
|
7826
|
-
if (audioCount) parts.push(
|
|
7827
|
-
if (fileCount) parts.push(
|
|
7828
|
-
return parts.join(", ") || "
|
|
7885
|
+
if (imageCount) parts.push(getAttachmentCountPreviewLabel("image", imageCount));
|
|
7886
|
+
if (videoCount) parts.push(getAttachmentCountPreviewLabel("video", videoCount));
|
|
7887
|
+
if (audioCount) parts.push(getAttachmentCountPreviewLabel("audio", audioCount));
|
|
7888
|
+
if (fileCount) parts.push(getAttachmentCountPreviewLabel("file", fileCount));
|
|
7889
|
+
return parts.join(", ") || getAttachmentTypePreviewLabel("file");
|
|
7829
7890
|
}
|
|
7830
7891
|
function mapSavedMessageAttachments(msg, messageObj, ctx) {
|
|
7831
7892
|
const loggedUserId = String(ctx.loggedUserDetails?._id || "");
|
|
@@ -7887,11 +7948,19 @@ function resolveSavedMessageContent(messageObj, msg) {
|
|
|
7887
7948
|
}
|
|
7888
7949
|
return { content: filename, messageType: "file", previewUrl: void 0 };
|
|
7889
7950
|
}
|
|
7890
|
-
if (messageType === "image")
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
if (messageType === "
|
|
7894
|
-
|
|
7951
|
+
if (messageType === "image") {
|
|
7952
|
+
return { content: getAttachmentTypePreviewLabel("image"), messageType, previewUrl: void 0 };
|
|
7953
|
+
}
|
|
7954
|
+
if (messageType === "video") {
|
|
7955
|
+
return { content: getAttachmentTypePreviewLabel("video"), messageType, previewUrl: void 0 };
|
|
7956
|
+
}
|
|
7957
|
+
if (messageType === "audio") {
|
|
7958
|
+
return { content: getAttachmentTypePreviewLabel("audio"), messageType, previewUrl: void 0 };
|
|
7959
|
+
}
|
|
7960
|
+
if (messageType === "file") {
|
|
7961
|
+
return { content: getAttachmentTypePreviewLabel("file"), messageType, previewUrl: void 0 };
|
|
7962
|
+
}
|
|
7963
|
+
return { content: getAttachmentTypePreviewLabel("file"), messageType, previewUrl: void 0 };
|
|
7895
7964
|
}
|
|
7896
7965
|
function getMessageId(msg) {
|
|
7897
7966
|
if (msg?.messageId && typeof msg.messageId === "object") {
|
|
@@ -7925,7 +7994,7 @@ function readSenderFromRecord(record) {
|
|
|
7925
7994
|
}
|
|
7926
7995
|
function resolveSenderName(msg, ctx) {
|
|
7927
7996
|
const messageObj = getMessageObject(msg);
|
|
7928
|
-
const
|
|
7997
|
+
const messageId2 = getMessageId(msg);
|
|
7929
7998
|
const loggedId = String(ctx.loggedUserDetails?._id || "");
|
|
7930
7999
|
const tryRecord = (record) => {
|
|
7931
8000
|
const parsed = readSenderFromRecord(record);
|
|
@@ -7942,9 +8011,9 @@ function resolveSenderName(msg, ctx) {
|
|
|
7942
8011
|
const hit = tryRecord(record);
|
|
7943
8012
|
if (hit) return hit;
|
|
7944
8013
|
}
|
|
7945
|
-
if (
|
|
8014
|
+
if (messageId2 && ctx.conversationMessages?.length) {
|
|
7946
8015
|
const found = ctx.conversationMessages.find(
|
|
7947
|
-
(m) => String(m._id || m.id) === String(
|
|
8016
|
+
(m) => String(m._id || m.id) === String(messageId2)
|
|
7948
8017
|
);
|
|
7949
8018
|
if (found) {
|
|
7950
8019
|
const hit = tryRecord(found);
|
|
@@ -7995,7 +8064,7 @@ function parseSavedMessage(msg, ctx = {}) {
|
|
|
7995
8064
|
const mode = ctx.mode || "pinned";
|
|
7996
8065
|
const prefs = ctx.dateTimePrefs ?? {};
|
|
7997
8066
|
if (msg?.isAttachment) {
|
|
7998
|
-
const
|
|
8067
|
+
const messageId3 = String(msg.messageId || "");
|
|
7999
8068
|
const attachmentId2 = String(msg.attachmentId || msg._id || "");
|
|
8000
8069
|
const attachments2 = mapSavedMessageAttachments(msg, null, ctx);
|
|
8001
8070
|
const { content: content2, previewUrl: previewUrl2, messageType: messageType2 } = resolveSavedMessageContent(null, msg);
|
|
@@ -8003,8 +8072,8 @@ function parseSavedMessage(msg, ctx = {}) {
|
|
|
8003
8072
|
const actionAt2 = msg?.createdAt || msg?.updatedAt || "";
|
|
8004
8073
|
const bodyText2 = String(msg.attachment?.caption || "").trim() || void 0;
|
|
8005
8074
|
return {
|
|
8006
|
-
id: attachmentId2 ||
|
|
8007
|
-
messageId:
|
|
8075
|
+
id: attachmentId2 || messageId3,
|
|
8076
|
+
messageId: messageId3,
|
|
8008
8077
|
attachmentId: attachmentId2 || void 0,
|
|
8009
8078
|
content: content2,
|
|
8010
8079
|
bodyText: bodyText2,
|
|
@@ -8023,7 +8092,7 @@ function parseSavedMessage(msg, ctx = {}) {
|
|
|
8023
8092
|
}
|
|
8024
8093
|
const messageObj = getMessageObject(msg);
|
|
8025
8094
|
const id = getMessageId(msg);
|
|
8026
|
-
const
|
|
8095
|
+
const messageId2 = id;
|
|
8027
8096
|
const attachmentId = msg?.attachmentId ? String(msg.attachmentId) : void 0;
|
|
8028
8097
|
const attachments = mapSavedMessageAttachments(msg, messageObj, ctx);
|
|
8029
8098
|
const rawContent = messageObj?.content ?? msg?.content ?? msg?.messageId?.content ?? "";
|
|
@@ -8045,8 +8114,8 @@ function parseSavedMessage(msg, ctx = {}) {
|
|
|
8045
8114
|
metaLabel = "Starred by you";
|
|
8046
8115
|
}
|
|
8047
8116
|
return {
|
|
8048
|
-
id: attachmentId ? `${
|
|
8049
|
-
messageId,
|
|
8117
|
+
id: attachmentId ? `${messageId2}:${attachmentId}` : id,
|
|
8118
|
+
messageId: messageId2,
|
|
8050
8119
|
attachmentId,
|
|
8051
8120
|
content: displayContent,
|
|
8052
8121
|
bodyText,
|
|
@@ -8076,6 +8145,22 @@ function groupSavedMessages(items) {
|
|
|
8076
8145
|
}));
|
|
8077
8146
|
}
|
|
8078
8147
|
|
|
8148
|
+
// src/chat/lib/chat-attachment-display.ts
|
|
8149
|
+
init_chat_constants();
|
|
8150
|
+
function cleanAttachmentDisplayName(filename, fallback = "Attachment") {
|
|
8151
|
+
const trimmed = filename.trim();
|
|
8152
|
+
if (!trimmed) return fallback;
|
|
8153
|
+
let name = trimmed;
|
|
8154
|
+
const prefixPattern = new RegExp(`^\\d{${ATTACHMENT_FILENAME_TIMESTAMP_LENGTH}}_`);
|
|
8155
|
+
while (prefixPattern.test(name)) {
|
|
8156
|
+
name = name.slice(ATTACHMENT_FILENAME_TIMESTAMP_LENGTH + 1);
|
|
8157
|
+
}
|
|
8158
|
+
if (name.length > ATTACHMENT_FILENAME_TIMESTAMP_LENGTH && /^\d+$/.test(name.slice(0, ATTACHMENT_FILENAME_TIMESTAMP_LENGTH)) && name[ATTACHMENT_FILENAME_TIMESTAMP_LENGTH] !== "_") {
|
|
8159
|
+
name = name.slice(ATTACHMENT_FILENAME_TIMESTAMP_LENGTH);
|
|
8160
|
+
}
|
|
8161
|
+
return name.trim() || trimmed;
|
|
8162
|
+
}
|
|
8163
|
+
|
|
8079
8164
|
// src/chat/header/saved-message/saved-message-utils.ts
|
|
8080
8165
|
var AVATAR_PALETTES = [
|
|
8081
8166
|
"bg-violet-500/15 text-violet-600 dark:text-violet-300",
|
|
@@ -8497,6 +8582,18 @@ var MessageStatus = ({ status, isPending, className }) => {
|
|
|
8497
8582
|
) });
|
|
8498
8583
|
};
|
|
8499
8584
|
var MessageStatus_default = MessageStatus;
|
|
8585
|
+
function GroupSenderName({ name, className }) {
|
|
8586
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8587
|
+
"span",
|
|
8588
|
+
{
|
|
8589
|
+
className: cn(
|
|
8590
|
+
"block max-w-full truncate text-[13px] font-semibold leading-[1.15] tracking-tight text-(--chat-incoming-text)",
|
|
8591
|
+
className
|
|
8592
|
+
),
|
|
8593
|
+
children: name
|
|
8594
|
+
}
|
|
8595
|
+
);
|
|
8596
|
+
}
|
|
8500
8597
|
function ForwardDoubleIcon({ className }) {
|
|
8501
8598
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8502
8599
|
"svg",
|
|
@@ -8534,22 +8631,10 @@ function MessageForwardedLabel({ isSender, className, overlay }) {
|
|
|
8534
8631
|
}
|
|
8535
8632
|
);
|
|
8536
8633
|
}
|
|
8537
|
-
function GroupSenderName({ name, className }) {
|
|
8538
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8539
|
-
"span",
|
|
8540
|
-
{
|
|
8541
|
-
className: cn(
|
|
8542
|
-
"block max-w-full truncate text-[13px] font-semibold leading-[1.15] tracking-tight text-(--chat-incoming-text)",
|
|
8543
|
-
className
|
|
8544
|
-
),
|
|
8545
|
-
children: name
|
|
8546
|
-
}
|
|
8547
|
-
);
|
|
8548
|
-
}
|
|
8549
8634
|
|
|
8550
8635
|
// src/chat/lib/chat-message-bubble.ts
|
|
8551
|
-
function getBubbleCornerClasses() {
|
|
8552
|
-
return "rounded-tl-[18px] rounded-tr-[18px] rounded-br-[18px] rounded-bl-none";
|
|
8636
|
+
function getBubbleCornerClasses(isSender) {
|
|
8637
|
+
return isSender ? "rounded-tl-[18px] rounded-tr-[18px] rounded-bl-[18px] rounded-br-none" : "rounded-tl-[18px] rounded-tr-[18px] rounded-br-[18px] rounded-bl-none";
|
|
8553
8638
|
}
|
|
8554
8639
|
function getChatBubbleClasses({
|
|
8555
8640
|
isSender = false,
|
|
@@ -8560,7 +8645,7 @@ function getChatBubbleClasses({
|
|
|
8560
8645
|
const isNeutral = resolvedSurface === "neutral";
|
|
8561
8646
|
return cn(
|
|
8562
8647
|
"relative",
|
|
8563
|
-
getBubbleCornerClasses(),
|
|
8648
|
+
getBubbleCornerClasses(isSender),
|
|
8564
8649
|
resolvedSurface === "sent" && "chat-bubble-sent bg-(--chat-theme) text-white",
|
|
8565
8650
|
resolvedSurface === "received" && "chat-bubble-received border border-(--chat-border)/60 bg-(--chat-incoming-bubble) text-(--chat-incoming-text)",
|
|
8566
8651
|
isNeutral && "chat-bubble-received border border-(--chat-border)/60 bg-(--chat-incoming-bubble) text-(--chat-incoming-text)",
|
|
@@ -8858,7 +8943,7 @@ function MessageAttachmentsCaptionBar({
|
|
|
8858
8943
|
onCancelEdit
|
|
8859
8944
|
}) {
|
|
8860
8945
|
if (isStandaloneMetaOnly) {
|
|
8861
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end pt-0.5", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
8946
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end pt-1.5 pb-0.5", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
8862
8947
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8863
8948
|
MessageCornerBadges,
|
|
8864
8949
|
{
|
|
@@ -10069,6 +10154,8 @@ function FileAttachmentRow({
|
|
|
10069
10154
|
}
|
|
10070
10155
|
window.open(fileUrl, "_blank", "noopener,noreferrer");
|
|
10071
10156
|
};
|
|
10157
|
+
const onThemeBubble = inBubble && isSender;
|
|
10158
|
+
const onIncomingBubble = inBubble && !isSender;
|
|
10072
10159
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10073
10160
|
"div",
|
|
10074
10161
|
{
|
|
@@ -10076,8 +10163,11 @@ function FileAttachmentRow({
|
|
|
10076
10163
|
"group w-full transition-opacity",
|
|
10077
10164
|
!stacked && "flex min-w-[220px] items-center gap-2",
|
|
10078
10165
|
stacked && "py-1.5",
|
|
10079
|
-
stacked && showDivider && (
|
|
10080
|
-
!stacked &&
|
|
10166
|
+
stacked && showDivider && (onThemeBubble ? "border-t border-white/15" : "border-t border-(--chat-border)/35"),
|
|
10167
|
+
!stacked && "rounded-xl border p-2.5",
|
|
10168
|
+
!stacked && onThemeBubble && "border-white/20 bg-white/12 text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.08)] backdrop-blur-[2px]",
|
|
10169
|
+
!stacked && onIncomingBubble && "border-(--chat-border)/70 bg-(--chat-elevated) text-(--chat-text) shadow-sm [.dark_&]:bg-(--chat-surface)",
|
|
10170
|
+
!stacked && !inBubble && "border-(--chat-border) bg-(--chat-surface) shadow-sm",
|
|
10081
10171
|
!fileUrl && "pointer-events-none opacity-60",
|
|
10082
10172
|
isCaptionActive && "opacity-90"
|
|
10083
10173
|
),
|
|
@@ -10089,36 +10179,31 @@ function FileAttachmentRow({
|
|
|
10089
10179
|
type: "button",
|
|
10090
10180
|
onClick: handleFileOpen,
|
|
10091
10181
|
disabled: !fileUrl || selectionMode,
|
|
10092
|
-
className: "flex min-w-0 flex-1 items-center gap-2 text-left disabled:cursor-default",
|
|
10182
|
+
className: "flex min-w-0 flex-1 items-center gap-2.5 text-left disabled:cursor-default",
|
|
10093
10183
|
children: [
|
|
10094
10184
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
|
|
10095
|
-
"flex shrink-0 items-center justify-center rounded-lg text-white",
|
|
10096
|
-
stacked ? "size-9" : "size-10 rounded-xl shadow-sm",
|
|
10185
|
+
"flex size-10 shrink-0 items-center justify-center rounded-lg text-white shadow-sm",
|
|
10097
10186
|
getAttachmentIconBoxClass(rawName)
|
|
10098
|
-
), children: getAttachmentIcon(rawName, "file", "text-white",
|
|
10187
|
+
), children: getAttachmentIcon(rawName, "file", "text-white", 18) }),
|
|
10099
10188
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
10100
10189
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
|
|
10101
|
-
"block truncate text-
|
|
10102
|
-
|
|
10190
|
+
"block truncate text-[12px] font-semibold leading-tight",
|
|
10191
|
+
onThemeBubble ? "text-white" : "text-(--chat-text)"
|
|
10103
10192
|
), children: displayName }),
|
|
10104
10193
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
|
|
10105
|
-
"mt-0.5 block truncate text-[10px] leading-tight uppercase",
|
|
10106
|
-
|
|
10194
|
+
"mt-0.5 block truncate text-[10px] font-medium leading-tight uppercase tracking-wide",
|
|
10195
|
+
onThemeBubble ? "text-white/70" : "text-(--chat-muted)"
|
|
10107
10196
|
), children: subtitle })
|
|
10108
10197
|
] }),
|
|
10109
10198
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
10110
10199
|
"span",
|
|
10111
10200
|
{
|
|
10112
10201
|
className: cn(
|
|
10113
|
-
"flex shrink-0 items-center justify-center transition-colors",
|
|
10114
|
-
|
|
10115
|
-
"size-7 rounded-lg border",
|
|
10116
|
-
inBubble && isSender ? "border-white/15 bg-white/10 text-white/80 group-hover:bg-white/15 group-hover:text-white" : "border-(--chat-border) bg-(--chat-elevated) text-(--chat-muted) group-hover:text-(--chat-theme)"
|
|
10117
|
-
),
|
|
10118
|
-
stacked && inBubble && isSender && "text-white/70 group-hover:text-white"
|
|
10202
|
+
"flex size-8 shrink-0 items-center justify-center rounded-full transition-colors",
|
|
10203
|
+
onThemeBubble ? "text-white/80 group-hover:bg-white/10 group-hover:text-white" : "text-(--chat-muted) group-hover:bg-(--chat-hover) group-hover:text-(--chat-theme)"
|
|
10119
10204
|
),
|
|
10120
10205
|
"aria-hidden": true,
|
|
10121
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { size:
|
|
10206
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { size: 14 })
|
|
10122
10207
|
}
|
|
10123
10208
|
)
|
|
10124
10209
|
]
|
|
@@ -10129,13 +10214,13 @@ function FileAttachmentRow({
|
|
|
10129
10214
|
{
|
|
10130
10215
|
onClick: onEditCaption,
|
|
10131
10216
|
label: `${attachmentCaption ? "Edit" : "Add"} caption for ${displayName}`,
|
|
10132
|
-
className:
|
|
10217
|
+
className: onThemeBubble ? "text-white/60 hover:text-white" : void 0
|
|
10133
10218
|
}
|
|
10134
10219
|
)
|
|
10135
10220
|
] }),
|
|
10136
10221
|
stacked && attachmentCaption ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn(
|
|
10137
|
-
"mt-1 whitespace-pre-wrap break-words pl-
|
|
10138
|
-
|
|
10222
|
+
"mt-1 whitespace-pre-wrap break-words pl-12 pr-8 text-[11px] leading-snug",
|
|
10223
|
+
onThemeBubble ? "text-white/85" : "text-(--chat-text-secondary)"
|
|
10139
10224
|
), children: attachmentCaption }) : null
|
|
10140
10225
|
]
|
|
10141
10226
|
}
|
|
@@ -10254,17 +10339,30 @@ function MessageAttachmentsNonImageSection({
|
|
|
10254
10339
|
att.id
|
|
10255
10340
|
);
|
|
10256
10341
|
};
|
|
10257
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10342
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full flex-col gap-1.5", children: nonImageGroups.map((group) => {
|
|
10258
10343
|
if (group.kind === "file-run") {
|
|
10259
10344
|
if (group.items.length === 1) {
|
|
10260
10345
|
return renderFileAttachmentFrame(group.items[0]);
|
|
10261
10346
|
}
|
|
10262
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10263
|
-
|
|
10264
|
-
|
|
10265
|
-
|
|
10266
|
-
|
|
10267
|
-
|
|
10347
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10348
|
+
"div",
|
|
10349
|
+
{
|
|
10350
|
+
className: cn(
|
|
10351
|
+
"w-full min-w-[220px]",
|
|
10352
|
+
isBubbleLayout && "rounded-xl border p-2",
|
|
10353
|
+
isBubbleLayout && isSender && "border-white/20 bg-white/12 shadow-[inset_0_1px_0_rgba(255,255,255,0.08)] backdrop-blur-[2px]",
|
|
10354
|
+
isBubbleLayout && !isSender && "border-(--chat-border)/70 bg-(--chat-elevated) shadow-sm [.dark_&]:bg-(--chat-surface)",
|
|
10355
|
+
!isBubbleLayout && "rounded-xl border border-(--chat-border) bg-(--chat-surface) p-2 shadow-sm"
|
|
10356
|
+
),
|
|
10357
|
+
children: group.items.map(
|
|
10358
|
+
(att2, index) => renderFileAttachmentFrame(att2, {
|
|
10359
|
+
stacked: true,
|
|
10360
|
+
showDivider: index > 0
|
|
10361
|
+
})
|
|
10362
|
+
)
|
|
10363
|
+
},
|
|
10364
|
+
`file-run-${group.items.map((item) => item.id).join("-")}`
|
|
10365
|
+
);
|
|
10268
10366
|
}
|
|
10269
10367
|
const att = group.item;
|
|
10270
10368
|
const type = resolveAttachmentType(att);
|
|
@@ -10337,7 +10435,8 @@ function MessageAttachmentsView({
|
|
|
10337
10435
|
isGroupedWithPrev = false,
|
|
10338
10436
|
isGroupedWithNext = false,
|
|
10339
10437
|
showSenderLabel = false,
|
|
10340
|
-
senderName
|
|
10438
|
+
senderName,
|
|
10439
|
+
senderId
|
|
10341
10440
|
}) {
|
|
10342
10441
|
const [documentPreview, setDocumentPreview] = React2.useState(null);
|
|
10343
10442
|
const visibleAttachments = getVisibleAttachments(attachments);
|
|
@@ -10378,7 +10477,10 @@ function MessageAttachmentsView({
|
|
|
10378
10477
|
isSender,
|
|
10379
10478
|
surface: bubbleSurface,
|
|
10380
10479
|
className: cn(
|
|
10381
|
-
isImageOnlyBubble ? "overflow-hidden p-0" : isForwarded || canShowSenderName ? "px-2 py-
|
|
10480
|
+
isImageOnlyBubble ? "overflow-hidden p-0" : isForwarded || canShowSenderName ? "px-2 py-1" : cn(
|
|
10481
|
+
"px-2.5",
|
|
10482
|
+
nonImages.length > 1 || images.length > 0 && nonImages.length > 0 ? "py-1.5" : "py-1"
|
|
10483
|
+
)
|
|
10382
10484
|
)
|
|
10383
10485
|
})
|
|
10384
10486
|
),
|
|
@@ -10391,7 +10493,13 @@ function MessageAttachmentsView({
|
|
|
10391
10493
|
isImageOnlyBubble ? "px-2.5 pt-1.5 pb-1" : "px-0.5 pb-0.5"
|
|
10392
10494
|
),
|
|
10393
10495
|
children: [
|
|
10394
|
-
canShowSenderName ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
10496
|
+
canShowSenderName ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
10497
|
+
GroupSenderName,
|
|
10498
|
+
{
|
|
10499
|
+
name: senderName,
|
|
10500
|
+
colorSeed: senderId || senderName
|
|
10501
|
+
}
|
|
10502
|
+
) : null,
|
|
10395
10503
|
showForwardedInHeader ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
10396
10504
|
MessageForwardedLabel,
|
|
10397
10505
|
{
|
|
@@ -10405,7 +10513,7 @@ function MessageAttachmentsView({
|
|
|
10405
10513
|
isBubbleLayout && replySnippet ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 pb-1", children: replySnippet }) : null,
|
|
10406
10514
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
|
|
10407
10515
|
"flex w-full flex-col",
|
|
10408
|
-
!isImageOnlyBubble && "gap-0",
|
|
10516
|
+
!isImageOnlyBubble && (images.length > 0 && nonImages.length > 0 ? "gap-1.5" : "gap-0"),
|
|
10409
10517
|
isImageOnlyBubble && "relative overflow-hidden"
|
|
10410
10518
|
), children: [
|
|
10411
10519
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -10935,7 +11043,7 @@ function collectConversationAttachments(messages) {
|
|
|
10935
11043
|
const items = [];
|
|
10936
11044
|
for (const message of messages) {
|
|
10937
11045
|
if (message?.isDeletedForEveryone) continue;
|
|
10938
|
-
const
|
|
11046
|
+
const messageId2 = String(message._id || message.id || "");
|
|
10939
11047
|
const createdAt = message.createdAt || message.timestamp;
|
|
10940
11048
|
const messageType = message.type || "text";
|
|
10941
11049
|
for (const attachment of message.attachments || []) {
|
|
@@ -10953,13 +11061,35 @@ function collectConversationAttachments(messages) {
|
|
|
10953
11061
|
url,
|
|
10954
11062
|
name,
|
|
10955
11063
|
type: resolveFileCategory(name, fileType, resolvedType),
|
|
10956
|
-
messageId,
|
|
11064
|
+
messageId: messageId2,
|
|
10957
11065
|
createdAt,
|
|
10958
11066
|
size: typeof attachment.size === "number" ? attachment.size : void 0,
|
|
10959
11067
|
duration: typeof attachment.duration === "number" ? attachment.duration : void 0,
|
|
10960
11068
|
fileType
|
|
10961
11069
|
});
|
|
10962
11070
|
}
|
|
11071
|
+
if ((message.attachments || []).length === 0) {
|
|
11072
|
+
const rootUrl = message.url || message.fileUrl || message.attachmentUrl || message.public_link || message.publicLink || "";
|
|
11073
|
+
if (!rootUrl) continue;
|
|
11074
|
+
const name = message.filename || message.fileName || message.name || "Attachment";
|
|
11075
|
+
const fileType = message.fileType || message.mimeType || "";
|
|
11076
|
+
const dedupeKey = `${rootUrl}|${name}`;
|
|
11077
|
+
if (seen.has(dedupeKey)) continue;
|
|
11078
|
+
seen.add(dedupeKey);
|
|
11079
|
+
const baseType = inferAttachmentType(fileType, name);
|
|
11080
|
+
const resolvedType = messageType === "image" && baseType === "file" ? "image" : baseType;
|
|
11081
|
+
items.push({
|
|
11082
|
+
id: String(message.attachmentId || message.fileId || dedupeKey),
|
|
11083
|
+
url: rootUrl,
|
|
11084
|
+
name,
|
|
11085
|
+
type: resolveFileCategory(name, fileType, resolvedType),
|
|
11086
|
+
messageId: messageId2,
|
|
11087
|
+
createdAt,
|
|
11088
|
+
size: typeof message.size === "number" ? message.size : void 0,
|
|
11089
|
+
duration: typeof message.duration === "number" ? message.duration : void 0,
|
|
11090
|
+
fileType
|
|
11091
|
+
});
|
|
11092
|
+
}
|
|
10963
11093
|
}
|
|
10964
11094
|
return items.sort(
|
|
10965
11095
|
(a, b) => new Date(b.createdAt || 0).getTime() - new Date(a.createdAt || 0).getTime()
|
|
@@ -11170,9 +11300,13 @@ function AttachmentSection({
|
|
|
11170
11300
|
}
|
|
11171
11301
|
var AttachmentsDrawer = ({ isOpen, onOpenChange, conversationId }) => {
|
|
11172
11302
|
const messagesByConversation = exports.useChatStore((s) => s.messagesByConversation);
|
|
11303
|
+
const messagesMetadata = exports.useChatStore((s) => s.messagesMetadata);
|
|
11304
|
+
const fetchMessages2 = exports.useChatStore((s) => s.fetchMessages);
|
|
11173
11305
|
const [sectionVisibleCount, setSectionVisibleCount] = React2.useState({});
|
|
11174
11306
|
const [documentPreview, setDocumentPreview] = React2.useState(null);
|
|
11175
11307
|
const [imageLightboxIndex, setImageLightboxIndex] = React2.useState(null);
|
|
11308
|
+
const hasLoadedMessages = conversationId ? Boolean(messagesMetadata[conversationId]?.isFirstPage) : false;
|
|
11309
|
+
const isLoading = isOpen && !!conversationId && !hasLoadedMessages;
|
|
11176
11310
|
React2.useEffect(() => {
|
|
11177
11311
|
if (!isOpen) {
|
|
11178
11312
|
setSectionVisibleCount({});
|
|
@@ -11183,6 +11317,10 @@ var AttachmentsDrawer = ({ isOpen, onOpenChange, conversationId }) => {
|
|
|
11183
11317
|
React2.useEffect(() => {
|
|
11184
11318
|
setSectionVisibleCount({});
|
|
11185
11319
|
}, [conversationId]);
|
|
11320
|
+
React2.useEffect(() => {
|
|
11321
|
+
if (!isOpen || !conversationId || hasLoadedMessages) return;
|
|
11322
|
+
fetchMessages2(conversationId);
|
|
11323
|
+
}, [isOpen, conversationId, hasLoadedMessages, fetchMessages2]);
|
|
11186
11324
|
const attachments = React2.useMemo(() => {
|
|
11187
11325
|
if (!conversationId) return [];
|
|
11188
11326
|
const messages = messagesByConversation[conversationId] || [];
|
|
@@ -11234,7 +11372,11 @@ var AttachmentsDrawer = ({ isOpen, onOpenChange, conversationId }) => {
|
|
|
11234
11372
|
] }),
|
|
11235
11373
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-[11px] text-(--chat-muted)", children: "Shared media and files" })
|
|
11236
11374
|
] }) }),
|
|
11237
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "chat-message-scroll flex-1 overflow-y-auto bg-(--chat-main-bg) px-2.5 py-2", children:
|
|
11375
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "chat-message-scroll flex-1 overflow-y-auto bg-(--chat-main-bg) px-2.5 py-2", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-[220px] flex-col items-center justify-center px-4 text-center", children: [
|
|
11376
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "mb-3 size-8 animate-spin text-(--chat-theme)" }),
|
|
11377
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[13px] font-medium text-(--chat-text)", children: "Loading attachments..." }),
|
|
11378
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-[11px] text-(--chat-muted)", children: "Fetching shared files for this chat" })
|
|
11379
|
+
] }) : attachments.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "chat-saved-empty flex min-h-[220px] flex-col items-center justify-center px-4 text-center", children: [
|
|
11238
11380
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-3", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "chat-saved-empty-icon-wrap", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Paperclip, { size: 22, className: cn("chat-saved-empty-icon !text-(--chat-theme)") }) }) }),
|
|
11239
11381
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[14px] font-semibold text-(--chat-text)", children: "No attachments" }),
|
|
11240
11382
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1.5 max-w-[240px] text-[12px] leading-relaxed text-(--chat-muted)", children: "Shared files will show up here." })
|
|
@@ -11617,7 +11759,7 @@ var ChannelDetailsDrawer = (props) => {
|
|
|
11617
11759
|
{
|
|
11618
11760
|
type: "button",
|
|
11619
11761
|
onClick: () => fileInputRef.current?.click(),
|
|
11620
|
-
className: "absolute -bottom-0.5 -right-0.5 flex size-6 items-center justify-center rounded-full border border-(--chat-border) bg-(--chat-surface) text-(--chat-
|
|
11762
|
+
className: "absolute -bottom-0.5 -right-0.5 flex size-6 items-center justify-center rounded-full border border-(--chat-border) bg-(--chat-surface) text-(--chat-theme) shadow-sm hover:bg-(--chat-theme-10)",
|
|
11621
11763
|
title: "Change group avatar",
|
|
11622
11764
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Camera, { size: 12 })
|
|
11623
11765
|
}
|
|
@@ -11656,7 +11798,7 @@ var ChannelDetailsDrawer = (props) => {
|
|
|
11656
11798
|
{
|
|
11657
11799
|
variant: "outline",
|
|
11658
11800
|
size: "sm",
|
|
11659
|
-
className: "h-8 flex-1 text-[12px]",
|
|
11801
|
+
className: "h-8 flex-1 border-(--chat-border) bg-(--chat-surface) text-[12px] text-(--chat-text) hover:bg-(--chat-hover)",
|
|
11660
11802
|
onClick: () => setIsEditing(false),
|
|
11661
11803
|
children: [
|
|
11662
11804
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "mr-1 size-3" }),
|
|
@@ -11668,7 +11810,7 @@ var ChannelDetailsDrawer = (props) => {
|
|
|
11668
11810
|
Button,
|
|
11669
11811
|
{
|
|
11670
11812
|
size: "sm",
|
|
11671
|
-
className: "h-8 flex-1 text-[12px]",
|
|
11813
|
+
className: "h-8 flex-1 border border-(--chat-theme) bg-(--chat-theme) text-[12px] text-white hover:opacity-90 disabled:opacity-50",
|
|
11672
11814
|
onClick: handleSave,
|
|
11673
11815
|
disabled: isSaving || imageUploadStatus === "uploading",
|
|
11674
11816
|
children: isSaving ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-3 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -11686,7 +11828,7 @@ var ChannelDetailsDrawer = (props) => {
|
|
|
11686
11828
|
{
|
|
11687
11829
|
variant: "ghost",
|
|
11688
11830
|
size: "sm",
|
|
11689
|
-
className: "mt-2 h-7 gap-1 px-2 text-[11px] text-(--chat-
|
|
11831
|
+
className: "mt-2 h-7 gap-1 px-2 text-[11px] text-(--chat-theme) hover:bg-(--chat-theme-10) hover:text-(--chat-theme)",
|
|
11690
11832
|
onClick: () => setIsEditing(true),
|
|
11691
11833
|
children: [
|
|
11692
11834
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "size-3" }),
|
|
@@ -12544,8 +12686,8 @@ function useChannelHeader({
|
|
|
12544
12686
|
}
|
|
12545
12687
|
}
|
|
12546
12688
|
};
|
|
12547
|
-
const handleSelectSearchResult = async (
|
|
12548
|
-
await fetchSearchMessageContext(
|
|
12689
|
+
const handleSelectSearchResult = async (messageId2) => {
|
|
12690
|
+
await fetchSearchMessageContext(messageId2);
|
|
12549
12691
|
handleCloseSearch();
|
|
12550
12692
|
};
|
|
12551
12693
|
const handleSearchOpenChange = (open) => {
|
|
@@ -12581,6 +12723,14 @@ function useChannelHeader({
|
|
|
12581
12723
|
fetchStarredMessages2(conversationId);
|
|
12582
12724
|
}
|
|
12583
12725
|
}, [state.isFavoriteOpen, conversationId, fetchStarredMessages2]);
|
|
12726
|
+
React2.useEffect(() => {
|
|
12727
|
+
if (state.isAttachmentsOpen && conversationId) {
|
|
12728
|
+
const meta = exports.useChatStore.getState().messagesMetadata[conversationId];
|
|
12729
|
+
if (!meta?.isFirstPage) {
|
|
12730
|
+
fetchMessagesStore(conversationId);
|
|
12731
|
+
}
|
|
12732
|
+
}
|
|
12733
|
+
}, [state.isAttachmentsOpen, conversationId, fetchMessagesStore]);
|
|
12584
12734
|
const pinnedCount = liveCounts?.pinnedCount ?? activeChannel?.pinnedCount ?? 0;
|
|
12585
12735
|
const starredCount = liveCounts?.starredCount ?? activeChannel?.starredCount ?? 0;
|
|
12586
12736
|
const handleClearChat = () => {
|
|
@@ -12626,14 +12776,14 @@ function useChannelHeader({
|
|
|
12626
12776
|
updateState({ isBlockAlertOpen: false });
|
|
12627
12777
|
}
|
|
12628
12778
|
};
|
|
12629
|
-
const handleUnpin = (
|
|
12779
|
+
const handleUnpin = (messageId2, attachmentId) => {
|
|
12630
12780
|
if (!loggedUserDetails?._id || !conversationId || !activeChannel) return;
|
|
12631
|
-
const loadingKey = attachmentId ? `${
|
|
12781
|
+
const loadingKey = attachmentId ? `${messageId2}:${attachmentId}` : messageId2;
|
|
12632
12782
|
updateState({ loadingIds: new Set(state.loadingIds).add(loadingKey) });
|
|
12633
12783
|
const basePayload = {
|
|
12634
12784
|
conversationId,
|
|
12635
12785
|
sender: loggedUserDetails._id,
|
|
12636
|
-
messageId,
|
|
12786
|
+
messageId: messageId2,
|
|
12637
12787
|
receiver: activeChannel.id,
|
|
12638
12788
|
...attachmentId ? { attachmentId } : {}
|
|
12639
12789
|
};
|
|
@@ -12653,12 +12803,12 @@ function useChannelHeader({
|
|
|
12653
12803
|
if (!dateStr) return "";
|
|
12654
12804
|
return formatLongDate(dateStr);
|
|
12655
12805
|
};
|
|
12656
|
-
const handleUnstar = (
|
|
12806
|
+
const handleUnstar = (messageId2, attachmentId) => {
|
|
12657
12807
|
if (!loggedUserDetails?._id || !conversationId || !activeChannel) return;
|
|
12658
|
-
const loadingKey = attachmentId ? `${
|
|
12808
|
+
const loadingKey = attachmentId ? `${messageId2}:${attachmentId}` : messageId2;
|
|
12659
12809
|
updateState({ loadingIds: new Set(state.loadingIds).add(loadingKey) });
|
|
12660
12810
|
const basePayload = {
|
|
12661
|
-
messageId,
|
|
12811
|
+
messageId: messageId2,
|
|
12662
12812
|
sender: loggedUserDetails._id,
|
|
12663
12813
|
conversationId,
|
|
12664
12814
|
receiver: activeChannel.id,
|
|
@@ -12928,7 +13078,7 @@ var MessageReactions = ({
|
|
|
12928
13078
|
{
|
|
12929
13079
|
onClick: () => onReactionClick(emoji),
|
|
12930
13080
|
className: cn(
|
|
12931
|
-
"flex items-center gap-
|
|
13081
|
+
"flex items-center gap-0.5 px-1.5 py-0.5 rounded-full text-[11px] border shadow-[0_1px_3px_rgba(15,23,42,0.08)] transition-all outline-none",
|
|
12932
13082
|
isReactedByMe ? "bg-(--chat-theme-10) border-(--chat-theme-20) text-(--chat-theme)" : "bg-(--chat-surface) border-(--chat-border) text-(--chat-text) hover:bg-(--chat-hover)"
|
|
12933
13083
|
),
|
|
12934
13084
|
children: [
|
|
@@ -12982,7 +13132,7 @@ var MessageToolbar = ({
|
|
|
12982
13132
|
"div",
|
|
12983
13133
|
{
|
|
12984
13134
|
className: cn(
|
|
12985
|
-
"absolute -top-8 z-
|
|
13135
|
+
"absolute -top-8 z-50 flex items-center gap-0.5 rounded-full border border-(--chat-border) p-0.5 shadow-md backdrop-blur-sm",
|
|
12986
13136
|
"bg-(--chat-toolbar-bg) text-(--chat-text)",
|
|
12987
13137
|
isSender ? "right-0" : "left-0"
|
|
12988
13138
|
),
|
|
@@ -13258,8 +13408,8 @@ init_useStore();
|
|
|
13258
13408
|
|
|
13259
13409
|
// src/chat/lib/chat-selection.ts
|
|
13260
13410
|
init_attachment_helpers();
|
|
13261
|
-
function buildSelectionKey(
|
|
13262
|
-
return pinKey(
|
|
13411
|
+
function buildSelectionKey(messageId2, attachmentId) {
|
|
13412
|
+
return pinKey(messageId2, attachmentId || null);
|
|
13263
13413
|
}
|
|
13264
13414
|
function parseSelectionKey(key) {
|
|
13265
13415
|
const colonIndex = key.indexOf(":");
|
|
@@ -13274,8 +13424,8 @@ function parseSelectionKey(key) {
|
|
|
13274
13424
|
function messageUsesAttachmentSelection(message) {
|
|
13275
13425
|
return getVisibleAttachments(message.attachments).length > 1;
|
|
13276
13426
|
}
|
|
13277
|
-
function getSelectedAttachmentIdsForMessage(selectedKeys,
|
|
13278
|
-
const prefix = `${
|
|
13427
|
+
function getSelectedAttachmentIdsForMessage(selectedKeys, messageId2) {
|
|
13428
|
+
const prefix = `${messageId2}:`;
|
|
13279
13429
|
const ids = /* @__PURE__ */ new Set();
|
|
13280
13430
|
selectedKeys.forEach((key) => {
|
|
13281
13431
|
if (key.startsWith(prefix)) {
|
|
@@ -13284,14 +13434,14 @@ function getSelectedAttachmentIdsForMessage(selectedKeys, messageId) {
|
|
|
13284
13434
|
});
|
|
13285
13435
|
return ids;
|
|
13286
13436
|
}
|
|
13287
|
-
function isMessageWhollySelected(selectedKeys,
|
|
13288
|
-
return selectedKeys.has(
|
|
13437
|
+
function isMessageWhollySelected(selectedKeys, messageId2) {
|
|
13438
|
+
return selectedKeys.has(messageId2);
|
|
13289
13439
|
}
|
|
13290
13440
|
function resolveForwardItems(selectedKeys, messages) {
|
|
13291
13441
|
const items = [];
|
|
13292
13442
|
selectedKeys.forEach((key) => {
|
|
13293
|
-
const { messageId, attachmentId } = parseSelectionKey(key);
|
|
13294
|
-
const message = messages.find((entry) => String(entry._id || entry.id) ===
|
|
13443
|
+
const { messageId: messageId2, attachmentId } = parseSelectionKey(key);
|
|
13444
|
+
const message = messages.find((entry) => String(entry._id || entry.id) === messageId2);
|
|
13295
13445
|
if (!message) return;
|
|
13296
13446
|
items.push({ message, attachmentId });
|
|
13297
13447
|
});
|
|
@@ -13317,7 +13467,7 @@ function useMessageItemActions({
|
|
|
13317
13467
|
message,
|
|
13318
13468
|
createdAt,
|
|
13319
13469
|
attachments,
|
|
13320
|
-
messageId,
|
|
13470
|
+
messageId: messageId2,
|
|
13321
13471
|
receiver,
|
|
13322
13472
|
isDeletedForEveryone,
|
|
13323
13473
|
reactions,
|
|
@@ -13369,10 +13519,10 @@ function useMessageItemActions({
|
|
|
13369
13519
|
const allUsers = exports.useChatStore((s) => s.allUsers);
|
|
13370
13520
|
const loggedUserDetails = exports.useChatStore((s) => s.loggedUserDetails);
|
|
13371
13521
|
const pinnedMessagesByConversation = exports.useChatStore((s) => s.pinnedMessagesByConversation);
|
|
13372
|
-
const mid = String(
|
|
13522
|
+
const mid = String(messageId2 || "");
|
|
13373
13523
|
const pendingActions = mid ? messagePendingActions[mid] || [] : [];
|
|
13374
13524
|
const isPending = Boolean(
|
|
13375
|
-
isSender && (String(
|
|
13525
|
+
isSender && (String(messageId2 || "").startsWith("temp-") || mid && (messagePendingActions[mid] || []).includes("send"))
|
|
13376
13526
|
);
|
|
13377
13527
|
const isEditPending = pendingActions.includes("edit");
|
|
13378
13528
|
const isDeletePending = pendingActions.includes("delete");
|
|
@@ -13410,13 +13560,13 @@ function useMessageItemActions({
|
|
|
13410
13560
|
};
|
|
13411
13561
|
const handleSaveAttachmentCaption = (caption, attachment) => {
|
|
13412
13562
|
const target = attachment ?? state.captionModalAttachment;
|
|
13413
|
-
if (!
|
|
13563
|
+
if (!messageId2 || !loggedUserDetails || !target) return;
|
|
13414
13564
|
const attachmentId = target.id;
|
|
13415
13565
|
if (isGroup) {
|
|
13416
13566
|
if (!conversationId) return;
|
|
13417
13567
|
emitGroupEdit({
|
|
13418
13568
|
content: caption,
|
|
13419
|
-
messageId,
|
|
13569
|
+
messageId: messageId2,
|
|
13420
13570
|
sender: loggedUserDetails._id,
|
|
13421
13571
|
conversationId,
|
|
13422
13572
|
attachmentId
|
|
@@ -13425,7 +13575,7 @@ function useMessageItemActions({
|
|
|
13425
13575
|
if (!receiver) return;
|
|
13426
13576
|
emitDmEdit({
|
|
13427
13577
|
content: caption,
|
|
13428
|
-
messageId,
|
|
13578
|
+
messageId: messageId2,
|
|
13429
13579
|
sender: loggedUserDetails._id,
|
|
13430
13580
|
receiver,
|
|
13431
13581
|
attachmentId
|
|
@@ -13442,12 +13592,12 @@ function useMessageItemActions({
|
|
|
13442
13592
|
onEnterSelectionMode?.();
|
|
13443
13593
|
};
|
|
13444
13594
|
const handleSaveEdit = () => {
|
|
13445
|
-
if (!
|
|
13595
|
+
if (!messageId2 || !loggedUserDetails) return;
|
|
13446
13596
|
if (isGroup) {
|
|
13447
13597
|
if (!conversationId) return;
|
|
13448
13598
|
emitGroupEdit({
|
|
13449
13599
|
content: state.editValue.trim(),
|
|
13450
|
-
messageId,
|
|
13600
|
+
messageId: messageId2,
|
|
13451
13601
|
sender: loggedUserDetails._id,
|
|
13452
13602
|
conversationId
|
|
13453
13603
|
});
|
|
@@ -13455,7 +13605,7 @@ function useMessageItemActions({
|
|
|
13455
13605
|
if (!receiver) return;
|
|
13456
13606
|
emitDmEdit({
|
|
13457
13607
|
content: state.editValue.trim(),
|
|
13458
|
-
messageId,
|
|
13608
|
+
messageId: messageId2,
|
|
13459
13609
|
sender: loggedUserDetails._id,
|
|
13460
13610
|
receiver
|
|
13461
13611
|
});
|
|
@@ -13466,7 +13616,7 @@ function useMessageItemActions({
|
|
|
13466
13616
|
updateState({ isEditing: false, editValue: message });
|
|
13467
13617
|
};
|
|
13468
13618
|
const handleDeleteMessage = (deleteType) => {
|
|
13469
|
-
if (!
|
|
13619
|
+
if (!messageId2 || !loggedUserDetails) return;
|
|
13470
13620
|
if (deleteType === "everyone" && !isSender) return;
|
|
13471
13621
|
if (deleteType === "everyone" && !isWithinEditWindow()) return;
|
|
13472
13622
|
const attachmentIds = hasAttachments ? deleteAttachmentIds : [];
|
|
@@ -13474,7 +13624,7 @@ function useMessageItemActions({
|
|
|
13474
13624
|
if (isGroup) {
|
|
13475
13625
|
if (!conversationId) return;
|
|
13476
13626
|
emitGroupDelete({
|
|
13477
|
-
messageId,
|
|
13627
|
+
messageId: messageId2,
|
|
13478
13628
|
sender: loggedUserDetails._id,
|
|
13479
13629
|
deleteType,
|
|
13480
13630
|
conversationId,
|
|
@@ -13483,7 +13633,7 @@ function useMessageItemActions({
|
|
|
13483
13633
|
} else {
|
|
13484
13634
|
if (!receiver) return;
|
|
13485
13635
|
emitDmDelete({
|
|
13486
|
-
messageId,
|
|
13636
|
+
messageId: messageId2,
|
|
13487
13637
|
sender: loggedUserDetails._id,
|
|
13488
13638
|
receiver,
|
|
13489
13639
|
deleteType,
|
|
@@ -13505,7 +13655,7 @@ function useMessageItemActions({
|
|
|
13505
13655
|
onForward?.();
|
|
13506
13656
|
};
|
|
13507
13657
|
const handleReactionClick = (emojiObject) => {
|
|
13508
|
-
if (!
|
|
13658
|
+
if (!messageId2 || !loggedUserDetails) return;
|
|
13509
13659
|
const reaction = typeof emojiObject === "string" ? emojiObject : emojiObject.emoji || emojiObject.native;
|
|
13510
13660
|
const hasReacted = reactions?.some(
|
|
13511
13661
|
(r) => r.reaction === reaction && String(r.addedBy?._id || r.addedBy || r.sender?._id || r.sender) === String(loggedUserDetails._id)
|
|
@@ -13514,7 +13664,7 @@ function useMessageItemActions({
|
|
|
13514
13664
|
if (isGroup) {
|
|
13515
13665
|
if (!conversationId) return;
|
|
13516
13666
|
emitGroupReactionRemove({
|
|
13517
|
-
messageId,
|
|
13667
|
+
messageId: messageId2,
|
|
13518
13668
|
sender: loggedUserDetails._id,
|
|
13519
13669
|
reaction,
|
|
13520
13670
|
conversationId
|
|
@@ -13522,7 +13672,7 @@ function useMessageItemActions({
|
|
|
13522
13672
|
} else {
|
|
13523
13673
|
if (!receiver) return;
|
|
13524
13674
|
emitDmReactionRemove({
|
|
13525
|
-
messageId,
|
|
13675
|
+
messageId: messageId2,
|
|
13526
13676
|
sender: loggedUserDetails._id,
|
|
13527
13677
|
receiver,
|
|
13528
13678
|
reaction,
|
|
@@ -13533,7 +13683,7 @@ function useMessageItemActions({
|
|
|
13533
13683
|
if (isGroup) {
|
|
13534
13684
|
if (!conversationId) return;
|
|
13535
13685
|
emitGroupReactionAdd({
|
|
13536
|
-
messageId,
|
|
13686
|
+
messageId: messageId2,
|
|
13537
13687
|
sender: loggedUserDetails._id,
|
|
13538
13688
|
reaction,
|
|
13539
13689
|
conversationId
|
|
@@ -13541,7 +13691,7 @@ function useMessageItemActions({
|
|
|
13541
13691
|
} else {
|
|
13542
13692
|
if (!receiver) return;
|
|
13543
13693
|
emitDmReactionAdd({
|
|
13544
|
-
messageId,
|
|
13694
|
+
messageId: messageId2,
|
|
13545
13695
|
sender: loggedUserDetails._id,
|
|
13546
13696
|
receiver,
|
|
13547
13697
|
reaction,
|
|
@@ -13551,7 +13701,7 @@ function useMessageItemActions({
|
|
|
13551
13701
|
}
|
|
13552
13702
|
};
|
|
13553
13703
|
const handlePinClick = () => {
|
|
13554
|
-
if (!
|
|
13704
|
+
if (!messageId2 || !loggedUserDetails) return;
|
|
13555
13705
|
if (isPinned) {
|
|
13556
13706
|
if (!isPinnedByMe) return;
|
|
13557
13707
|
if (isGroup) {
|
|
@@ -13559,14 +13709,14 @@ function useMessageItemActions({
|
|
|
13559
13709
|
emitGroupUnpin({
|
|
13560
13710
|
conversationId,
|
|
13561
13711
|
sender: loggedUserDetails._id,
|
|
13562
|
-
messageId,
|
|
13712
|
+
messageId: messageId2,
|
|
13563
13713
|
receiver: ""
|
|
13564
13714
|
});
|
|
13565
13715
|
} else {
|
|
13566
13716
|
emitDmUnpin({
|
|
13567
13717
|
conversationId,
|
|
13568
13718
|
sender: loggedUserDetails._id,
|
|
13569
|
-
messageId,
|
|
13719
|
+
messageId: messageId2,
|
|
13570
13720
|
receiver: receiver || ""
|
|
13571
13721
|
});
|
|
13572
13722
|
}
|
|
@@ -13576,32 +13726,32 @@ function useMessageItemActions({
|
|
|
13576
13726
|
emitGroupPin({
|
|
13577
13727
|
conversationId,
|
|
13578
13728
|
sender: loggedUserDetails._id,
|
|
13579
|
-
messageId,
|
|
13729
|
+
messageId: messageId2,
|
|
13580
13730
|
receiver: ""
|
|
13581
13731
|
});
|
|
13582
13732
|
} else {
|
|
13583
13733
|
emitDmPin({
|
|
13584
13734
|
conversationId,
|
|
13585
13735
|
sender: loggedUserDetails._id,
|
|
13586
|
-
messageId,
|
|
13736
|
+
messageId: messageId2,
|
|
13587
13737
|
receiver: receiver || ""
|
|
13588
13738
|
});
|
|
13589
13739
|
}
|
|
13590
13740
|
}
|
|
13591
13741
|
};
|
|
13592
13742
|
const handleStarClick = () => {
|
|
13593
|
-
if (!
|
|
13743
|
+
if (!messageId2 || !loggedUserDetails || !conversationId) return;
|
|
13594
13744
|
if (isStarred) {
|
|
13595
13745
|
if (isGroup) {
|
|
13596
|
-
emitGroupUnstar({ messageId, sender: loggedUserDetails._id, conversationId });
|
|
13746
|
+
emitGroupUnstar({ messageId: messageId2, sender: loggedUserDetails._id, conversationId });
|
|
13597
13747
|
} else {
|
|
13598
|
-
emitDmUnstar({ messageId, sender: loggedUserDetails._id, conversationId });
|
|
13748
|
+
emitDmUnstar({ messageId: messageId2, sender: loggedUserDetails._id, conversationId });
|
|
13599
13749
|
}
|
|
13600
13750
|
} else {
|
|
13601
13751
|
if (isGroup) {
|
|
13602
|
-
emitGroupStar({ messageId, sender: loggedUserDetails._id, conversationId });
|
|
13752
|
+
emitGroupStar({ messageId: messageId2, sender: loggedUserDetails._id, conversationId });
|
|
13603
13753
|
} else {
|
|
13604
|
-
emitDmStar({ messageId, sender: loggedUserDetails._id, conversationId });
|
|
13754
|
+
emitDmStar({ messageId: messageId2, sender: loggedUserDetails._id, conversationId });
|
|
13605
13755
|
}
|
|
13606
13756
|
}
|
|
13607
13757
|
};
|
|
@@ -13823,6 +13973,7 @@ function MessageItemTextBubble({
|
|
|
13823
13973
|
isForwarded,
|
|
13824
13974
|
showSenderLabel,
|
|
13825
13975
|
senderName,
|
|
13976
|
+
senderId,
|
|
13826
13977
|
replyTo,
|
|
13827
13978
|
loggedUserDetails,
|
|
13828
13979
|
allUsers,
|
|
@@ -13861,7 +14012,13 @@ function MessageItemTextBubble({
|
|
|
13861
14012
|
),
|
|
13862
14013
|
children: [
|
|
13863
14014
|
(canShowSenderName || isForwarded) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
13864
|
-
canShowSenderName ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
14015
|
+
canShowSenderName ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
14016
|
+
GroupSenderName,
|
|
14017
|
+
{
|
|
14018
|
+
name: senderName,
|
|
14019
|
+
colorSeed: senderId || senderName
|
|
14020
|
+
}
|
|
14021
|
+
) : null,
|
|
13865
14022
|
isForwarded ? /* @__PURE__ */ jsxRuntime.jsx(MessageForwardedLabel, { isSender, className: "px-0 pt-0 pb-0" }) : null
|
|
13866
14023
|
] }),
|
|
13867
14024
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -13912,7 +14069,7 @@ function MessageItemTextBubble({
|
|
|
13912
14069
|
}
|
|
13913
14070
|
)
|
|
13914
14071
|
] })
|
|
13915
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-
|
|
14072
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
13916
14073
|
hasText && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "whitespace-pre-wrap break-words leading-snug", children: [
|
|
13917
14074
|
message,
|
|
13918
14075
|
isEdited && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -13970,6 +14127,7 @@ function MessageItemAttachmentBubble({
|
|
|
13970
14127
|
isGroupedWithNext,
|
|
13971
14128
|
showSenderLabel,
|
|
13972
14129
|
senderName,
|
|
14130
|
+
senderId,
|
|
13973
14131
|
formattedTime,
|
|
13974
14132
|
status,
|
|
13975
14133
|
isPending,
|
|
@@ -14018,6 +14176,7 @@ function MessageItemAttachmentBubble({
|
|
|
14018
14176
|
isGroupedWithNext,
|
|
14019
14177
|
showSenderLabel,
|
|
14020
14178
|
senderName,
|
|
14179
|
+
senderId,
|
|
14021
14180
|
formattedTime,
|
|
14022
14181
|
status,
|
|
14023
14182
|
isPending,
|
|
@@ -14077,6 +14236,7 @@ function MessageItemView(props) {
|
|
|
14077
14236
|
isGroup,
|
|
14078
14237
|
isHighlighted,
|
|
14079
14238
|
senderName,
|
|
14239
|
+
senderId,
|
|
14080
14240
|
senderImage,
|
|
14081
14241
|
showSenderLabel,
|
|
14082
14242
|
senderAvatarImage,
|
|
@@ -14253,6 +14413,7 @@ function MessageItemView(props) {
|
|
|
14253
14413
|
isGroupedWithNext,
|
|
14254
14414
|
showSenderLabel,
|
|
14255
14415
|
senderName,
|
|
14416
|
+
senderId,
|
|
14256
14417
|
formattedTime,
|
|
14257
14418
|
status,
|
|
14258
14419
|
isPending,
|
|
@@ -14294,6 +14455,7 @@ function MessageItemView(props) {
|
|
|
14294
14455
|
isForwarded,
|
|
14295
14456
|
showSenderLabel,
|
|
14296
14457
|
senderName,
|
|
14458
|
+
senderId,
|
|
14297
14459
|
replyTo,
|
|
14298
14460
|
loggedUserDetails,
|
|
14299
14461
|
allUsers,
|
|
@@ -14484,6 +14646,28 @@ function MessageSelectionBar({
|
|
|
14484
14646
|
|
|
14485
14647
|
// src/chat/active-channel-messages/utils.ts
|
|
14486
14648
|
var getMessageSenderId2 = (msg) => msg ? String(msg.senderId || msg.sender?._id || "") : "";
|
|
14649
|
+
var isLikelyObjectId = (value) => /^[a-f\d]{24}$/i.test(value);
|
|
14650
|
+
function resolveGroupSenderDisplay(message, allUsers = [], participants = []) {
|
|
14651
|
+
const senderId = getMessageSenderId2(message);
|
|
14652
|
+
if (senderId) {
|
|
14653
|
+
const fromUsers = allUsers.find((user) => String(user._id) === senderId);
|
|
14654
|
+
if (fromUsers?.name?.trim()) {
|
|
14655
|
+
return { name: fromUsers.name.trim(), image: fromUsers.image };
|
|
14656
|
+
}
|
|
14657
|
+
const fromParticipants = participants.find((participant) => {
|
|
14658
|
+
const id = typeof participant === "string" ? participant : participant?._id;
|
|
14659
|
+
return String(id) === senderId;
|
|
14660
|
+
});
|
|
14661
|
+
if (fromParticipants && typeof fromParticipants === "object" && fromParticipants.name?.trim()) {
|
|
14662
|
+
return { name: fromParticipants.name.trim(), image: fromParticipants.image };
|
|
14663
|
+
}
|
|
14664
|
+
}
|
|
14665
|
+
const sender = message.sender;
|
|
14666
|
+
if (typeof sender === "string" && sender.trim() && !isLikelyObjectId(sender.trim())) {
|
|
14667
|
+
return { name: sender.trim(), image: message.senderImage };
|
|
14668
|
+
}
|
|
14669
|
+
return { name: "User", image: void 0 };
|
|
14670
|
+
}
|
|
14487
14671
|
var isSameMessageSide = (a, b, isGroupChat) => {
|
|
14488
14672
|
if (!!a.isOwnMessage !== !!b.isOwnMessage) return false;
|
|
14489
14673
|
if (a.isOwnMessage) return true;
|
|
@@ -14497,8 +14681,8 @@ function canDeleteSelectionForEveryone(selectedKeys, messages, isGroup) {
|
|
|
14497
14681
|
const parsed = [...selectedKeys].map((key) => parseSelectionKey(key));
|
|
14498
14682
|
const messageIds = new Set(parsed.map((entry) => entry.messageId));
|
|
14499
14683
|
if (messageIds.size !== 1) return false;
|
|
14500
|
-
const
|
|
14501
|
-
const message = messages.find((entry) => String(entry._id || entry.id) ===
|
|
14684
|
+
const messageId2 = [...messageIds][0];
|
|
14685
|
+
const message = messages.find((entry) => String(entry._id || entry.id) === messageId2);
|
|
14502
14686
|
if (!message?.isOwnMessage) return false;
|
|
14503
14687
|
if (!isWithinMessageEditWindow(message.timestamp, isGroup)) return false;
|
|
14504
14688
|
const hasAttachmentKey = parsed.some((entry) => entry.attachmentId);
|
|
@@ -14512,6 +14696,9 @@ function canDeleteSelectionForEveryone(selectedKeys, messages, isGroup) {
|
|
|
14512
14696
|
});
|
|
14513
14697
|
}
|
|
14514
14698
|
|
|
14699
|
+
// src/chat/active-channel-messages/ActiveChannelMessagesView.tsx
|
|
14700
|
+
init_useStore();
|
|
14701
|
+
|
|
14515
14702
|
// src/chat/active-channel-messages/useActiveChannelMessages.ts
|
|
14516
14703
|
init_useStore();
|
|
14517
14704
|
init_store_helpers();
|
|
@@ -14527,6 +14714,7 @@ function mapApiMessage(m, activeChannel, conversationId, loggedUserId, activeCon
|
|
|
14527
14714
|
content: m.content,
|
|
14528
14715
|
sender: m.sender?.name || "User",
|
|
14529
14716
|
senderId: String(m.sender?._id || m.sender || ""),
|
|
14717
|
+
senderImage: m.sender?.image,
|
|
14530
14718
|
receiver: activeChannel?.id,
|
|
14531
14719
|
timestamp: m.createdAt,
|
|
14532
14720
|
isOwnMessage: isOwn,
|
|
@@ -14554,7 +14742,101 @@ function mapApiMessage(m, activeChannel, conversationId, loggedUserId, activeCon
|
|
|
14554
14742
|
};
|
|
14555
14743
|
}
|
|
14556
14744
|
|
|
14745
|
+
// src/chat/active-channel-messages/jump-to-date.ts
|
|
14746
|
+
function startOfLocalDay(date) {
|
|
14747
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
|
|
14748
|
+
}
|
|
14749
|
+
function toDateInputValue(date) {
|
|
14750
|
+
const y = date.getFullYear();
|
|
14751
|
+
const m = String(date.getMonth() + 1).padStart(2, "0");
|
|
14752
|
+
const d = String(date.getDate()).padStart(2, "0");
|
|
14753
|
+
return `${y}-${m}-${d}`;
|
|
14754
|
+
}
|
|
14755
|
+
function clampJumpDate(picked, minDay, maxDay) {
|
|
14756
|
+
if (!Number.isFinite(minDay) || !Number.isFinite(maxDay) || minDay > maxDay) return null;
|
|
14757
|
+
const at = startOfLocalDay(picked);
|
|
14758
|
+
const clamped = Math.min(Math.max(at, minDay), maxDay);
|
|
14759
|
+
return new Date(clamped);
|
|
14760
|
+
}
|
|
14761
|
+
function resolveJumpDateBounds(createdAt, oldestMessageTimestamp, now = /* @__PURE__ */ new Date()) {
|
|
14762
|
+
const today = startOfLocalDay(now);
|
|
14763
|
+
const createdDay = createdAt ? startOfLocalDay(new Date(createdAt)) : null;
|
|
14764
|
+
const oldestDay = oldestMessageTimestamp ? startOfLocalDay(new Date(oldestMessageTimestamp)) : null;
|
|
14765
|
+
let minDay = today;
|
|
14766
|
+
if (createdDay != null && oldestDay != null) {
|
|
14767
|
+
minDay = Math.max(createdDay, oldestDay);
|
|
14768
|
+
} else if (oldestDay != null) {
|
|
14769
|
+
minDay = oldestDay;
|
|
14770
|
+
} else if (createdDay != null) {
|
|
14771
|
+
minDay = createdDay;
|
|
14772
|
+
}
|
|
14773
|
+
return { minDay: Math.min(minDay, today), maxDay: today };
|
|
14774
|
+
}
|
|
14775
|
+
function resolveJumpPreset(preset, now = /* @__PURE__ */ new Date()) {
|
|
14776
|
+
const day = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
14777
|
+
if (preset === "today") return day.getTime();
|
|
14778
|
+
if (preset === "yesterday") {
|
|
14779
|
+
day.setDate(day.getDate() - 1);
|
|
14780
|
+
return day.getTime();
|
|
14781
|
+
}
|
|
14782
|
+
if (preset === "lastWeek") {
|
|
14783
|
+
day.setDate(day.getDate() - 7);
|
|
14784
|
+
return day.getTime();
|
|
14785
|
+
}
|
|
14786
|
+
day.setMonth(day.getMonth() - 1);
|
|
14787
|
+
return day.getTime();
|
|
14788
|
+
}
|
|
14789
|
+
function messageId(m) {
|
|
14790
|
+
return String(m._id || m.id);
|
|
14791
|
+
}
|
|
14792
|
+
function findNearestMessageByDay(messages, targetDay) {
|
|
14793
|
+
let best = messages[0];
|
|
14794
|
+
let bestDist = Infinity;
|
|
14795
|
+
let bestDay = startOfLocalDay(new Date(best.timestamp));
|
|
14796
|
+
for (const m of messages) {
|
|
14797
|
+
const day = startOfLocalDay(new Date(m.timestamp));
|
|
14798
|
+
const dist = Math.abs(day - targetDay);
|
|
14799
|
+
if (dist < bestDist || dist === bestDist && day < bestDay) {
|
|
14800
|
+
best = m;
|
|
14801
|
+
bestDist = dist;
|
|
14802
|
+
bestDay = day;
|
|
14803
|
+
}
|
|
14804
|
+
}
|
|
14805
|
+
return best;
|
|
14806
|
+
}
|
|
14807
|
+
function resolveJumpStep(messages, pending, hasMore) {
|
|
14808
|
+
if (messages.length === 0) {
|
|
14809
|
+
return hasMore ? { action: "loadOlder" } : { action: "done" };
|
|
14810
|
+
}
|
|
14811
|
+
if (pending.kind === "beginning") {
|
|
14812
|
+
if (hasMore) return { action: "loadOlder" };
|
|
14813
|
+
return { action: "scroll", messageId: messageId(messages[0]) };
|
|
14814
|
+
}
|
|
14815
|
+
const oldestDay = startOfLocalDay(new Date(messages[0].timestamp));
|
|
14816
|
+
if (hasMore && oldestDay > pending.at) {
|
|
14817
|
+
return { action: "loadOlder" };
|
|
14818
|
+
}
|
|
14819
|
+
const onDay = messages.find(
|
|
14820
|
+
(m) => startOfLocalDay(new Date(m.timestamp)) === pending.at
|
|
14821
|
+
);
|
|
14822
|
+
if (onDay) {
|
|
14823
|
+
return { action: "scroll", messageId: messageId(onDay) };
|
|
14824
|
+
}
|
|
14825
|
+
const nearest = findNearestMessageByDay(messages, pending.at);
|
|
14826
|
+
return { action: "scroll", messageId: messageId(nearest) };
|
|
14827
|
+
}
|
|
14828
|
+
function smoothScrollToMessage(container, messageEl) {
|
|
14829
|
+
const containerRect = container.getBoundingClientRect();
|
|
14830
|
+
const messageRect = messageEl.getBoundingClientRect();
|
|
14831
|
+
const delta = messageRect.top - containerRect.top - Math.min(120, container.clientHeight * 0.25);
|
|
14832
|
+
container.scrollTo({
|
|
14833
|
+
top: Math.max(0, container.scrollTop + delta),
|
|
14834
|
+
behavior: "smooth"
|
|
14835
|
+
});
|
|
14836
|
+
}
|
|
14837
|
+
|
|
14557
14838
|
// src/chat/active-channel-messages/useActiveChannelMessages.ts
|
|
14839
|
+
var MAX_JUMP_OLDER_PAGES = 40;
|
|
14558
14840
|
function useActiveChannelMessages({
|
|
14559
14841
|
activeChannel,
|
|
14560
14842
|
loggedUserId,
|
|
@@ -14577,6 +14859,11 @@ function useActiveChannelMessages({
|
|
|
14577
14859
|
const previousMessageCountRef = React2.useRef(0);
|
|
14578
14860
|
const previousLastMessageIdRef = React2.useRef(null);
|
|
14579
14861
|
const [enteringMessageIds, setEnteringMessageIds] = React2.useState(/* @__PURE__ */ new Set());
|
|
14862
|
+
const [showScrollToBottom, setShowScrollToBottom] = React2.useState(false);
|
|
14863
|
+
const stickToBottomRef = React2.useRef(true);
|
|
14864
|
+
const pendingJumpRef = React2.useRef(null);
|
|
14865
|
+
const jumpPagesRef = React2.useRef(0);
|
|
14866
|
+
const [jumpNonce, setJumpNonce] = React2.useState(0);
|
|
14580
14867
|
const { fetchMessages: fetchMessages2, messagesMetadata, deletedForMeIds, searchedMessageId, isSearchActive, setSearchActive, setSearchedMessageId, fetchSearchMessageContext } = exports.useChatStore();
|
|
14581
14868
|
const loggedUserImage = exports.useChatStore((s) => s.loggedUserDetails?.image);
|
|
14582
14869
|
const conversations = exports.useChatStore((s) => s.conversations);
|
|
@@ -14600,6 +14887,13 @@ function useActiveChannelMessages({
|
|
|
14600
14887
|
})),
|
|
14601
14888
|
[displayMessages, messagesById, loggedUserId]
|
|
14602
14889
|
);
|
|
14890
|
+
const jumpDateBounds = React2.useMemo(
|
|
14891
|
+
() => resolveJumpDateBounds(
|
|
14892
|
+
conversationInfo?.createdAt,
|
|
14893
|
+
displayMessages[0]?.timestamp
|
|
14894
|
+
),
|
|
14895
|
+
[conversationInfo?.createdAt, displayMessages]
|
|
14896
|
+
);
|
|
14603
14897
|
React2.useEffect(() => {
|
|
14604
14898
|
const messages = messagesWithResolvedReplies;
|
|
14605
14899
|
const lastMessage = messages[messages.length - 1];
|
|
@@ -14637,6 +14931,10 @@ function useActiveChannelMessages({
|
|
|
14637
14931
|
previousMessageCountRef.current = 0;
|
|
14638
14932
|
previousLastMessageIdRef.current = null;
|
|
14639
14933
|
setEnteringMessageIds(/* @__PURE__ */ new Set());
|
|
14934
|
+
pendingJumpRef.current = null;
|
|
14935
|
+
jumpPagesRef.current = 0;
|
|
14936
|
+
stickToBottomRef.current = true;
|
|
14937
|
+
setShowScrollToBottom(false);
|
|
14640
14938
|
}, [conversationId, clearSelection]);
|
|
14641
14939
|
const onSelectionModeChangeRef = React2.useRef(onSelectionModeChange);
|
|
14642
14940
|
React2.useEffect(() => {
|
|
@@ -14646,10 +14944,10 @@ function useActiveChannelMessages({
|
|
|
14646
14944
|
onSelectionModeChangeRef.current?.(selectionMode);
|
|
14647
14945
|
}, [selectionMode]);
|
|
14648
14946
|
const toggleSelection = React2.useCallback((message, attachmentId) => {
|
|
14649
|
-
const
|
|
14650
|
-
if (!
|
|
14947
|
+
const messageId2 = String(message._id || message.id);
|
|
14948
|
+
if (!messageId2) return;
|
|
14651
14949
|
const useAttachmentSelection = messageUsesAttachmentSelection(message);
|
|
14652
|
-
const key = useAttachmentSelection && attachmentId ? buildSelectionKey(
|
|
14950
|
+
const key = useAttachmentSelection && attachmentId ? buildSelectionKey(messageId2, attachmentId) : messageId2;
|
|
14653
14951
|
setSelectedKeys((prev) => {
|
|
14654
14952
|
const next = new Set(prev);
|
|
14655
14953
|
if (next.has(key)) next.delete(key);
|
|
@@ -14659,17 +14957,17 @@ function useActiveChannelMessages({
|
|
|
14659
14957
|
});
|
|
14660
14958
|
}, []);
|
|
14661
14959
|
const enterSelectionMode = React2.useCallback((message, attachmentId) => {
|
|
14662
|
-
const
|
|
14663
|
-
if (!
|
|
14960
|
+
const messageId2 = String(message._id || message.id);
|
|
14961
|
+
if (!messageId2) return;
|
|
14664
14962
|
setSelectionMode(true);
|
|
14665
14963
|
const useAttachmentSelection = messageUsesAttachmentSelection(message);
|
|
14666
14964
|
if (useAttachmentSelection) {
|
|
14667
14965
|
if (attachmentId) {
|
|
14668
|
-
setSelectedKeys((prev) => new Set(prev).add(buildSelectionKey(
|
|
14966
|
+
setSelectedKeys((prev) => new Set(prev).add(buildSelectionKey(messageId2, attachmentId)));
|
|
14669
14967
|
}
|
|
14670
14968
|
return;
|
|
14671
14969
|
}
|
|
14672
|
-
setSelectedKeys((prev) => new Set(prev).add(
|
|
14970
|
+
setSelectedKeys((prev) => new Set(prev).add(messageId2));
|
|
14673
14971
|
}, []);
|
|
14674
14972
|
const selectedForwardItems = resolveForwardItems(selectedKeys, displayMessages);
|
|
14675
14973
|
const canDeleteForEveryone = React2.useMemo(
|
|
@@ -14688,14 +14986,14 @@ function useActiveChannelMessages({
|
|
|
14688
14986
|
}
|
|
14689
14987
|
const isGroupChat = !!activeChannel?.isGroup;
|
|
14690
14988
|
selectedKeys.forEach((key) => {
|
|
14691
|
-
const { messageId, attachmentId } = parseSelectionKey(key);
|
|
14692
|
-
if (!
|
|
14693
|
-
const message = displayMessages.find((entry) => String(entry._id || entry.id) ===
|
|
14989
|
+
const { messageId: messageId2, attachmentId } = parseSelectionKey(key);
|
|
14990
|
+
if (!messageId2 || messageId2.startsWith("temp-")) return;
|
|
14991
|
+
const message = displayMessages.find((entry) => String(entry._id || entry.id) === messageId2);
|
|
14694
14992
|
if (isGroupChat) {
|
|
14695
14993
|
const convId = String(message?.conversationId || conversationId || "");
|
|
14696
14994
|
if (!convId) return;
|
|
14697
14995
|
emitGroupDelete({
|
|
14698
|
-
messageId,
|
|
14996
|
+
messageId: messageId2,
|
|
14699
14997
|
sender: loggedUserDetails._id,
|
|
14700
14998
|
deleteType,
|
|
14701
14999
|
conversationId: convId,
|
|
@@ -14705,7 +15003,7 @@ function useActiveChannelMessages({
|
|
|
14705
15003
|
const receiver = message?.receiver || activeChannel?.id;
|
|
14706
15004
|
if (!receiver) return;
|
|
14707
15005
|
emitDmDelete({
|
|
14708
|
-
messageId,
|
|
15006
|
+
messageId: messageId2,
|
|
14709
15007
|
sender: loggedUserDetails._id,
|
|
14710
15008
|
receiver: String(receiver),
|
|
14711
15009
|
deleteType,
|
|
@@ -14744,43 +15042,138 @@ function useActiveChannelMessages({
|
|
|
14744
15042
|
fetchMessages2(conversationId);
|
|
14745
15043
|
}
|
|
14746
15044
|
};
|
|
14747
|
-
const handleReplyTargetClick = async (
|
|
14748
|
-
if (!
|
|
14749
|
-
|
|
14750
|
-
|
|
15045
|
+
const handleReplyTargetClick = async (messageId2) => {
|
|
15046
|
+
if (!messageId2) return;
|
|
15047
|
+
stickToBottomRef.current = false;
|
|
15048
|
+
if (messagesById.has(messageId2)) {
|
|
15049
|
+
setSearchedMessageId(messageId2);
|
|
14751
15050
|
return;
|
|
14752
15051
|
}
|
|
14753
|
-
await fetchSearchMessageContext(
|
|
15052
|
+
await fetchSearchMessageContext(messageId2, { searchMode: false });
|
|
14754
15053
|
};
|
|
15054
|
+
const handleJumpTo = React2.useCallback((preset, specificDate) => {
|
|
15055
|
+
stickToBottomRef.current = false;
|
|
15056
|
+
if (preset === "beginning") {
|
|
15057
|
+
pendingJumpRef.current = { kind: "beginning" };
|
|
15058
|
+
} else if (preset === "specific") {
|
|
15059
|
+
if (!specificDate) return;
|
|
15060
|
+
const clamped = clampJumpDate(
|
|
15061
|
+
specificDate,
|
|
15062
|
+
jumpDateBounds.minDay,
|
|
15063
|
+
jumpDateBounds.maxDay
|
|
15064
|
+
);
|
|
15065
|
+
if (!clamped) return;
|
|
15066
|
+
pendingJumpRef.current = { kind: "date", at: startOfLocalDay(clamped) };
|
|
15067
|
+
} else {
|
|
15068
|
+
const raw = resolveJumpPreset(preset);
|
|
15069
|
+
const at = Math.min(Math.max(raw, jumpDateBounds.minDay), jumpDateBounds.maxDay);
|
|
15070
|
+
pendingJumpRef.current = { kind: "date", at };
|
|
15071
|
+
}
|
|
15072
|
+
jumpPagesRef.current = 0;
|
|
15073
|
+
setJumpNonce((n) => n + 1);
|
|
15074
|
+
}, [jumpDateBounds.minDay, jumpDateBounds.maxDay]);
|
|
15075
|
+
React2.useEffect(() => {
|
|
15076
|
+
const pending = pendingJumpRef.current;
|
|
15077
|
+
if (!pending || isLoading) return;
|
|
15078
|
+
const step = resolveJumpStep(
|
|
15079
|
+
messagesWithResolvedReplies,
|
|
15080
|
+
pending,
|
|
15081
|
+
!!currentMeta?.hasMore
|
|
15082
|
+
);
|
|
15083
|
+
if (step.action === "loadOlder") {
|
|
15084
|
+
if (!conversationId || !currentMeta?.nextCursor || jumpPagesRef.current >= MAX_JUMP_OLDER_PAGES) {
|
|
15085
|
+
pendingJumpRef.current = null;
|
|
15086
|
+
const fallback = messagesWithResolvedReplies[0];
|
|
15087
|
+
if (fallback) setSearchedMessageId(String(fallback._id || fallback.id));
|
|
15088
|
+
return;
|
|
15089
|
+
}
|
|
15090
|
+
jumpPagesRef.current += 1;
|
|
15091
|
+
const prevScrollHeight = scrollContainerRef.current?.scrollHeight ?? 0;
|
|
15092
|
+
fetchMessages2(conversationId, DEFAULT_MESSAGES_LIMIT, currentMeta.nextCursor).then(() => {
|
|
15093
|
+
if (scrollContainerRef.current && prevScrollHeight) {
|
|
15094
|
+
scrollContainerRef.current.scrollTop = scrollContainerRef.current.scrollHeight - prevScrollHeight;
|
|
15095
|
+
}
|
|
15096
|
+
});
|
|
15097
|
+
return;
|
|
15098
|
+
}
|
|
15099
|
+
pendingJumpRef.current = null;
|
|
15100
|
+
if (step.action === "scroll") {
|
|
15101
|
+
setSearchedMessageId(null);
|
|
15102
|
+
requestAnimationFrame(() => setSearchedMessageId(step.messageId));
|
|
15103
|
+
}
|
|
15104
|
+
}, [
|
|
15105
|
+
jumpNonce,
|
|
15106
|
+
isLoading,
|
|
15107
|
+
messagesWithResolvedReplies,
|
|
15108
|
+
currentMeta?.hasMore,
|
|
15109
|
+
currentMeta?.nextCursor,
|
|
15110
|
+
conversationId,
|
|
15111
|
+
fetchMessages2,
|
|
15112
|
+
setSearchedMessageId
|
|
15113
|
+
]);
|
|
15114
|
+
const updateScrollToBottomVisibility = React2.useCallback((el) => {
|
|
15115
|
+
const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
15116
|
+
const nearBottom = distanceFromBottom <= 96;
|
|
15117
|
+
stickToBottomRef.current = nearBottom;
|
|
15118
|
+
setShowScrollToBottom(!nearBottom);
|
|
15119
|
+
}, []);
|
|
15120
|
+
const handleScrollToBottom = React2.useCallback(() => {
|
|
15121
|
+
stickToBottomRef.current = true;
|
|
15122
|
+
if (isSearchActive) {
|
|
15123
|
+
setSearchActive(false);
|
|
15124
|
+
setSearchedMessageId(null);
|
|
15125
|
+
if (conversationId) fetchMessages2(conversationId);
|
|
15126
|
+
setShowScrollToBottom(false);
|
|
15127
|
+
return;
|
|
15128
|
+
}
|
|
15129
|
+
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
15130
|
+
setShowScrollToBottom(false);
|
|
15131
|
+
}, [isSearchActive, conversationId, setSearchActive, setSearchedMessageId, fetchMessages2]);
|
|
14755
15132
|
const handleScroll = (e) => {
|
|
14756
15133
|
const target = e.currentTarget;
|
|
15134
|
+
updateScrollToBottomVisibility(target);
|
|
15135
|
+
if (pendingJumpRef.current) return;
|
|
14757
15136
|
if (target.scrollTop === 0 && currentMeta?.hasMore && !isLoading && conversationId && currentMeta.nextCursor) {
|
|
14758
15137
|
const prevScrollHeight = target.scrollHeight;
|
|
14759
15138
|
fetchMessages2(conversationId, DEFAULT_MESSAGES_LIMIT, currentMeta.nextCursor).then(() => {
|
|
14760
15139
|
if (scrollContainerRef.current) {
|
|
14761
15140
|
const newScrollHeight = scrollContainerRef.current.scrollHeight;
|
|
14762
15141
|
scrollContainerRef.current.scrollTop = newScrollHeight - prevScrollHeight;
|
|
15142
|
+
updateScrollToBottomVisibility(scrollContainerRef.current);
|
|
14763
15143
|
}
|
|
14764
15144
|
});
|
|
14765
15145
|
}
|
|
14766
15146
|
};
|
|
14767
15147
|
React2.useLayoutEffect(() => {
|
|
14768
|
-
if (!isInitialLoading &&
|
|
15148
|
+
if (!isInitialLoading && stickToBottomRef.current && !pendingJumpRef.current) {
|
|
14769
15149
|
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
14770
15150
|
}
|
|
14771
|
-
}, [messagesWithResolvedReplies.length, isInitialLoading
|
|
15151
|
+
}, [messagesWithResolvedReplies.length, isInitialLoading]);
|
|
14772
15152
|
React2.useEffect(() => {
|
|
14773
15153
|
if (searchedMessageId && !isLoading) {
|
|
15154
|
+
stickToBottomRef.current = false;
|
|
15155
|
+
const container = scrollContainerRef.current;
|
|
14774
15156
|
const element = document.getElementById(`message-${searchedMessageId}`);
|
|
14775
|
-
if (element) {
|
|
14776
|
-
|
|
15157
|
+
if (container && element) {
|
|
15158
|
+
requestAnimationFrame(() => {
|
|
15159
|
+
requestAnimationFrame(() => {
|
|
15160
|
+
smoothScrollToMessage(container, element);
|
|
15161
|
+
updateScrollToBottomVisibility(container);
|
|
15162
|
+
});
|
|
15163
|
+
});
|
|
14777
15164
|
}
|
|
14778
15165
|
if (!isSearchActive) {
|
|
14779
15166
|
const timer = window.setTimeout(() => setSearchedMessageId(null), 2500);
|
|
14780
15167
|
return () => window.clearTimeout(timer);
|
|
14781
15168
|
}
|
|
14782
15169
|
}
|
|
14783
|
-
}, [
|
|
15170
|
+
}, [
|
|
15171
|
+
searchedMessageId,
|
|
15172
|
+
isLoading,
|
|
15173
|
+
isSearchActive,
|
|
15174
|
+
setSearchedMessageId,
|
|
15175
|
+
updateScrollToBottomVisibility
|
|
15176
|
+
]);
|
|
14784
15177
|
return {
|
|
14785
15178
|
activeChannel,
|
|
14786
15179
|
conversationId,
|
|
@@ -14806,11 +15199,297 @@ function useActiveChannelMessages({
|
|
|
14806
15199
|
canDeleteForEveryone,
|
|
14807
15200
|
handleResetToNormal,
|
|
14808
15201
|
handleReplyTargetClick,
|
|
15202
|
+
handleJumpTo,
|
|
15203
|
+
jumpDateBounds,
|
|
15204
|
+
showScrollToBottom,
|
|
15205
|
+
handleScrollToBottom,
|
|
14809
15206
|
handleScroll
|
|
14810
15207
|
};
|
|
14811
15208
|
}
|
|
15209
|
+
function Calendar({
|
|
15210
|
+
className,
|
|
15211
|
+
classNames,
|
|
15212
|
+
showOutsideDays = true,
|
|
15213
|
+
captionLayout = "label",
|
|
15214
|
+
buttonVariant = "ghost",
|
|
15215
|
+
formatters,
|
|
15216
|
+
components,
|
|
15217
|
+
...props
|
|
15218
|
+
}) {
|
|
15219
|
+
const defaultClassNames = reactDayPicker.getDefaultClassNames();
|
|
15220
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15221
|
+
reactDayPicker.DayPicker,
|
|
15222
|
+
{
|
|
15223
|
+
showOutsideDays,
|
|
15224
|
+
className: cn(
|
|
15225
|
+
"group/calendar bg-background p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
|
|
15226
|
+
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
|
15227
|
+
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
|
|
15228
|
+
className
|
|
15229
|
+
),
|
|
15230
|
+
captionLayout,
|
|
15231
|
+
formatters: {
|
|
15232
|
+
formatMonthDropdown: (date) => date.toLocaleString("default", { month: "short" }),
|
|
15233
|
+
...formatters
|
|
15234
|
+
},
|
|
15235
|
+
classNames: {
|
|
15236
|
+
root: cn("w-fit", defaultClassNames.root),
|
|
15237
|
+
months: cn(
|
|
15238
|
+
"relative flex flex-col gap-4 md:flex-row",
|
|
15239
|
+
defaultClassNames.months
|
|
15240
|
+
),
|
|
15241
|
+
month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
|
|
15242
|
+
nav: cn(
|
|
15243
|
+
"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
|
|
15244
|
+
defaultClassNames.nav
|
|
15245
|
+
),
|
|
15246
|
+
button_previous: cn(
|
|
15247
|
+
buttonVariants({ variant: buttonVariant }),
|
|
15248
|
+
"size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
|
|
15249
|
+
defaultClassNames.button_previous
|
|
15250
|
+
),
|
|
15251
|
+
button_next: cn(
|
|
15252
|
+
buttonVariants({ variant: buttonVariant }),
|
|
15253
|
+
"size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
|
|
15254
|
+
defaultClassNames.button_next
|
|
15255
|
+
),
|
|
15256
|
+
month_caption: cn(
|
|
15257
|
+
"flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)",
|
|
15258
|
+
defaultClassNames.month_caption
|
|
15259
|
+
),
|
|
15260
|
+
dropdowns: cn(
|
|
15261
|
+
"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium",
|
|
15262
|
+
defaultClassNames.dropdowns
|
|
15263
|
+
),
|
|
15264
|
+
dropdown_root: cn(
|
|
15265
|
+
"relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50",
|
|
15266
|
+
defaultClassNames.dropdown_root
|
|
15267
|
+
),
|
|
15268
|
+
dropdown: cn(
|
|
15269
|
+
"absolute inset-0 bg-popover opacity-0",
|
|
15270
|
+
defaultClassNames.dropdown
|
|
15271
|
+
),
|
|
15272
|
+
caption_label: cn(
|
|
15273
|
+
"font-medium select-none",
|
|
15274
|
+
captionLayout === "label" ? "text-sm" : "flex h-8 items-center gap-1 rounded-md pr-1 pl-2 text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground",
|
|
15275
|
+
defaultClassNames.caption_label
|
|
15276
|
+
),
|
|
15277
|
+
month_grid: cn("w-full border-collapse", defaultClassNames.month_grid),
|
|
15278
|
+
weekdays: cn("flex", defaultClassNames.weekdays),
|
|
15279
|
+
weekday: cn(
|
|
15280
|
+
"flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none",
|
|
15281
|
+
defaultClassNames.weekday
|
|
15282
|
+
),
|
|
15283
|
+
week: cn("mt-2 flex w-full", defaultClassNames.week),
|
|
15284
|
+
week_number_header: cn(
|
|
15285
|
+
"w-(--cell-size) select-none",
|
|
15286
|
+
defaultClassNames.week_number_header
|
|
15287
|
+
),
|
|
15288
|
+
week_number: cn(
|
|
15289
|
+
"text-[0.8rem] text-muted-foreground select-none",
|
|
15290
|
+
defaultClassNames.week_number
|
|
15291
|
+
),
|
|
15292
|
+
day: cn(
|
|
15293
|
+
"group/day relative aspect-square h-full w-full p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-md",
|
|
15294
|
+
props.showWeekNumber ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-md" : "[&:first-child[data-selected=true]_button]:rounded-l-md",
|
|
15295
|
+
defaultClassNames.day
|
|
15296
|
+
),
|
|
15297
|
+
range_start: cn(
|
|
15298
|
+
"rounded-l-md bg-accent",
|
|
15299
|
+
defaultClassNames.range_start
|
|
15300
|
+
),
|
|
15301
|
+
range_middle: cn("rounded-none", defaultClassNames.range_middle),
|
|
15302
|
+
range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
|
|
15303
|
+
today: cn(
|
|
15304
|
+
"rounded-md bg-accent text-accent-foreground data-[selected=true]:rounded-none",
|
|
15305
|
+
defaultClassNames.today
|
|
15306
|
+
),
|
|
15307
|
+
outside: cn(
|
|
15308
|
+
"text-muted-foreground aria-selected:text-muted-foreground",
|
|
15309
|
+
defaultClassNames.outside
|
|
15310
|
+
),
|
|
15311
|
+
disabled: cn(
|
|
15312
|
+
"text-muted-foreground opacity-50",
|
|
15313
|
+
defaultClassNames.disabled
|
|
15314
|
+
),
|
|
15315
|
+
hidden: cn("invisible", defaultClassNames.hidden),
|
|
15316
|
+
...classNames
|
|
15317
|
+
},
|
|
15318
|
+
components: {
|
|
15319
|
+
Root: ({ className: className2, rootRef, ...props2 }) => {
|
|
15320
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15321
|
+
"div",
|
|
15322
|
+
{
|
|
15323
|
+
"data-slot": "calendar",
|
|
15324
|
+
ref: rootRef,
|
|
15325
|
+
className: cn(className2),
|
|
15326
|
+
...props2
|
|
15327
|
+
}
|
|
15328
|
+
);
|
|
15329
|
+
},
|
|
15330
|
+
Chevron: ({ className: className2, orientation, ...props2 }) => {
|
|
15331
|
+
if (orientation === "left") {
|
|
15332
|
+
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, { className: cn("size-4", className2), ...props2 });
|
|
15333
|
+
}
|
|
15334
|
+
if (orientation === "right") {
|
|
15335
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15336
|
+
lucideReact.ChevronRightIcon,
|
|
15337
|
+
{
|
|
15338
|
+
className: cn("size-4", className2),
|
|
15339
|
+
...props2
|
|
15340
|
+
}
|
|
15341
|
+
);
|
|
15342
|
+
}
|
|
15343
|
+
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: cn("size-4", className2), ...props2 });
|
|
15344
|
+
},
|
|
15345
|
+
DayButton: CalendarDayButton,
|
|
15346
|
+
WeekNumber: ({ children, ...props2 }) => {
|
|
15347
|
+
return /* @__PURE__ */ jsxRuntime.jsx("td", { ...props2, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-(--cell-size) items-center justify-center text-center", children }) });
|
|
15348
|
+
},
|
|
15349
|
+
...components
|
|
15350
|
+
},
|
|
15351
|
+
...props
|
|
15352
|
+
}
|
|
15353
|
+
);
|
|
15354
|
+
}
|
|
15355
|
+
function CalendarDayButton({
|
|
15356
|
+
className,
|
|
15357
|
+
day,
|
|
15358
|
+
modifiers,
|
|
15359
|
+
...props
|
|
15360
|
+
}) {
|
|
15361
|
+
const defaultClassNames = reactDayPicker.getDefaultClassNames();
|
|
15362
|
+
const ref = React2__namespace.useRef(null);
|
|
15363
|
+
React2__namespace.useEffect(() => {
|
|
15364
|
+
if (modifiers.focused) ref.current?.focus();
|
|
15365
|
+
}, [modifiers.focused]);
|
|
15366
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15367
|
+
Button,
|
|
15368
|
+
{
|
|
15369
|
+
ref,
|
|
15370
|
+
variant: "ghost",
|
|
15371
|
+
size: "icon",
|
|
15372
|
+
"data-day": day.date.toLocaleDateString(),
|
|
15373
|
+
"data-selected-single": modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle,
|
|
15374
|
+
"data-range-start": modifiers.range_start,
|
|
15375
|
+
"data-range-end": modifiers.range_end,
|
|
15376
|
+
"data-range-middle": modifiers.range_middle,
|
|
15377
|
+
className: cn(
|
|
15378
|
+
"flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-accent-foreground [&>span]:text-xs [&>span]:opacity-70",
|
|
15379
|
+
defaultClassNames.day,
|
|
15380
|
+
className
|
|
15381
|
+
),
|
|
15382
|
+
...props
|
|
15383
|
+
}
|
|
15384
|
+
);
|
|
15385
|
+
}
|
|
15386
|
+
var PRESETS = [
|
|
15387
|
+
{ preset: "today", label: "Today" },
|
|
15388
|
+
{ preset: "yesterday", label: "Yesterday" },
|
|
15389
|
+
{ preset: "lastWeek", label: "Last week" },
|
|
15390
|
+
{ preset: "lastMonth", label: "Last month" },
|
|
15391
|
+
{ preset: "beginning", label: "The very beginning" }
|
|
15392
|
+
];
|
|
15393
|
+
function ChatDateJumpMenu({ label, minDay, maxDay, onJump }) {
|
|
15394
|
+
const { scopeClassName } = useChatTheme();
|
|
15395
|
+
const [open, setOpen] = React2.useState(false);
|
|
15396
|
+
const [showCalendar, setShowCalendar] = React2.useState(false);
|
|
15397
|
+
const [calendarMonth, setCalendarMonth] = React2.useState(() => new Date(maxDay));
|
|
15398
|
+
const minDate = new Date(minDay);
|
|
15399
|
+
const maxDate = new Date(maxDay);
|
|
15400
|
+
React2.useEffect(() => {
|
|
15401
|
+
if (showCalendar) setCalendarMonth(new Date(maxDay));
|
|
15402
|
+
}, [showCalendar, maxDay]);
|
|
15403
|
+
const queueJump = (preset, specificDate) => {
|
|
15404
|
+
window.setTimeout(() => onJump(preset, specificDate), 0);
|
|
15405
|
+
};
|
|
15406
|
+
const handleOpenChange = (next) => {
|
|
15407
|
+
setOpen(next);
|
|
15408
|
+
if (!next) setShowCalendar(false);
|
|
15409
|
+
};
|
|
15410
|
+
const handlePreset = (preset) => {
|
|
15411
|
+
setOpen(false);
|
|
15412
|
+
setShowCalendar(false);
|
|
15413
|
+
queueJump(preset);
|
|
15414
|
+
};
|
|
15415
|
+
const handleDateSelect = (date) => {
|
|
15416
|
+
if (!date) return;
|
|
15417
|
+
const clamped = clampJumpDate(date, minDay, maxDay);
|
|
15418
|
+
if (!clamped) return;
|
|
15419
|
+
setOpen(false);
|
|
15420
|
+
setShowCalendar(false);
|
|
15421
|
+
queueJump("specific", clamped);
|
|
15422
|
+
};
|
|
15423
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
|
|
15424
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
15425
|
+
"button",
|
|
15426
|
+
{
|
|
15427
|
+
type: "button",
|
|
15428
|
+
className: "chat-date-divider-pill chat-date-divider-pill--interactive",
|
|
15429
|
+
"aria-label": `Jump to date, currently ${label}`,
|
|
15430
|
+
children: [
|
|
15431
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
|
|
15432
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "chat-date-divider-chevron", "aria-hidden": true })
|
|
15433
|
+
]
|
|
15434
|
+
}
|
|
15435
|
+
) }),
|
|
15436
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
15437
|
+
PopoverContent,
|
|
15438
|
+
{
|
|
15439
|
+
align: "center",
|
|
15440
|
+
sideOffset: 8,
|
|
15441
|
+
className: cn(
|
|
15442
|
+
scopeClassName,
|
|
15443
|
+
chatPopoverContentClass,
|
|
15444
|
+
"w-auto overflow-hidden rounded-2xl p-0",
|
|
15445
|
+
showCalendar ? "min-w-[300px]" : "min-w-[220px]"
|
|
15446
|
+
),
|
|
15447
|
+
onCloseAutoFocus: (event) => event.preventDefault(),
|
|
15448
|
+
children: showCalendar ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15449
|
+
Calendar,
|
|
15450
|
+
{
|
|
15451
|
+
mode: "single",
|
|
15452
|
+
month: calendarMonth,
|
|
15453
|
+
onMonthChange: setCalendarMonth,
|
|
15454
|
+
startMonth: minDate,
|
|
15455
|
+
endMonth: maxDate,
|
|
15456
|
+
showOutsideDays: false,
|
|
15457
|
+
disabled: { before: minDate, after: maxDate },
|
|
15458
|
+
onSelect: handleDateSelect,
|
|
15459
|
+
className: "chat-jump-calendar rounded-xl bg-transparent p-1 [--cell-size:2.125rem]"
|
|
15460
|
+
}
|
|
15461
|
+
) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
15462
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 pt-3 pb-2", children: [
|
|
15463
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: chatOptionsMenuLabelClass, children: "Jump to\u2026" }),
|
|
15464
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 flex flex-col", children: PRESETS.map(({ preset, label: itemLabel }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
15465
|
+
"button",
|
|
15466
|
+
{
|
|
15467
|
+
type: "button",
|
|
15468
|
+
className: cn(chatOptionsMenuItemClass, "w-full border-0 bg-transparent text-left"),
|
|
15469
|
+
onClick: () => handlePreset(preset),
|
|
15470
|
+
children: itemLabel
|
|
15471
|
+
},
|
|
15472
|
+
preset
|
|
15473
|
+
)) })
|
|
15474
|
+
] }),
|
|
15475
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(chatOptionsMenuSeparatorClass, "mx-3") }),
|
|
15476
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-1 pb-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15477
|
+
"button",
|
|
15478
|
+
{
|
|
15479
|
+
type: "button",
|
|
15480
|
+
className: cn(chatOptionsMenuItemClass, "w-full border-0 bg-transparent text-left"),
|
|
15481
|
+
onClick: () => setShowCalendar(true),
|
|
15482
|
+
children: "Jump to a specific date"
|
|
15483
|
+
}
|
|
15484
|
+
) })
|
|
15485
|
+
] })
|
|
15486
|
+
}
|
|
15487
|
+
)
|
|
15488
|
+
] });
|
|
15489
|
+
}
|
|
14812
15490
|
var ActiveChannelMessagesView = (props) => {
|
|
14813
15491
|
const { formatDateDivider } = useChatLocale();
|
|
15492
|
+
const allUsers = exports.useChatStore((s) => s.allUsers);
|
|
14814
15493
|
const {
|
|
14815
15494
|
activeChannel,
|
|
14816
15495
|
conversationId,
|
|
@@ -14836,6 +15515,10 @@ var ActiveChannelMessagesView = (props) => {
|
|
|
14836
15515
|
canDeleteForEveryone,
|
|
14837
15516
|
handleResetToNormal,
|
|
14838
15517
|
handleReplyTargetClick,
|
|
15518
|
+
handleJumpTo,
|
|
15519
|
+
jumpDateBounds,
|
|
15520
|
+
showScrollToBottom,
|
|
15521
|
+
handleScrollToBottom,
|
|
14839
15522
|
handleScroll
|
|
14840
15523
|
} = useActiveChannelMessages(props);
|
|
14841
15524
|
const { onReply, onForward } = props;
|
|
@@ -14848,7 +15531,7 @@ var ActiveChannelMessagesView = (props) => {
|
|
|
14848
15531
|
] })
|
|
14849
15532
|
] });
|
|
14850
15533
|
}
|
|
14851
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "chat-message-canvas relative flex h-full
|
|
15534
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "chat-message-canvas relative flex h-full flex-col", children: [
|
|
14852
15535
|
isSearchActive && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-6 left-1/2 -translate-x-1/2 z-40 animate-in slide-in-from-top-4 duration-500", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center overflow-hidden rounded-2xl border border-(--chat-border) bg-(--chat-surface) shadow-lg ring-4 ring-(--chat-surface)", children: [
|
|
14853
15536
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 bg-(--chat-theme) px-4 py-2.5", children: [
|
|
14854
15537
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.History, { className: "size-3.5 animate-pulse text-white" }),
|
|
@@ -14885,11 +15568,20 @@ var ActiveChannelMessagesView = (props) => {
|
|
|
14885
15568
|
return groups;
|
|
14886
15569
|
}, {})
|
|
14887
15570
|
).map(([date, messages]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2 flex flex-col", children: [
|
|
14888
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "
|
|
15571
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-1.5 z-20 mb-2 flex justify-center py-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
15572
|
+
ChatDateJumpMenu,
|
|
15573
|
+
{
|
|
15574
|
+
label: date,
|
|
15575
|
+
minDay: jumpDateBounds.minDay,
|
|
15576
|
+
maxDay: jumpDateBounds.maxDay,
|
|
15577
|
+
onJump: handleJumpTo
|
|
15578
|
+
}
|
|
15579
|
+
) }),
|
|
14889
15580
|
messages.map((m, msgIndex) => {
|
|
14890
|
-
const senderLabel = typeof m.sender === "string" ? m.sender : "User";
|
|
14891
|
-
const senderImage = !m.isOwnMessage ? activeChannel?.isGroup ? void 0 : activeChannel?.image : void 0;
|
|
14892
15581
|
const isGroupChat = !!activeChannel?.isGroup;
|
|
15582
|
+
const participants = conversationInfo?.participants ?? [];
|
|
15583
|
+
const { name: senderLabel, image: groupSenderImage } = isGroupChat && !m.isOwnMessage ? resolveGroupSenderDisplay(m, allUsers, participants) : { name: typeof m.sender === "string" ? m.sender : "User", image: void 0 };
|
|
15584
|
+
const senderImage = !m.isOwnMessage ? isGroupChat ? groupSenderImage : activeChannel?.image : void 0;
|
|
14893
15585
|
const prevMessage = msgIndex > 0 ? messages[msgIndex - 1] : null;
|
|
14894
15586
|
const nextMessage = msgIndex < messages.length - 1 ? messages[msgIndex + 1] : null;
|
|
14895
15587
|
const isGroupedWithPrev = !!prevMessage && isSameMessageSide(prevMessage, m, isGroupChat);
|
|
@@ -14936,6 +15628,7 @@ var ActiveChannelMessagesView = (props) => {
|
|
|
14936
15628
|
conversationInfo,
|
|
14937
15629
|
isHighlighted: String(m._id || m.id) === String(searchedMessageId),
|
|
14938
15630
|
senderName: senderLabel,
|
|
15631
|
+
senderId: getMessageSenderId2(m),
|
|
14939
15632
|
senderImage,
|
|
14940
15633
|
showSenderName,
|
|
14941
15634
|
showSenderLabel,
|
|
@@ -14976,6 +15669,16 @@ var ActiveChannelMessagesView = (props) => {
|
|
|
14976
15669
|
onForward: handleBatchForward
|
|
14977
15670
|
}
|
|
14978
15671
|
),
|
|
15672
|
+
showScrollToBottom && !selectionMode && /* @__PURE__ */ jsxRuntime.jsx(
|
|
15673
|
+
"button",
|
|
15674
|
+
{
|
|
15675
|
+
type: "button",
|
|
15676
|
+
onClick: handleScrollToBottom,
|
|
15677
|
+
className: "chat-scroll-to-bottom",
|
|
15678
|
+
"aria-label": "Scroll to latest messages",
|
|
15679
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "size-5", strokeWidth: 2.25 })
|
|
15680
|
+
}
|
|
15681
|
+
),
|
|
14979
15682
|
isInitialLoading && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pointer-events-none absolute bottom-6 left-1/2 z-30 flex -translate-x-1/2 animate-in items-center gap-3 rounded-2xl border border-(--chat-border) bg-(--chat-surface)/80 px-5 py-2.5 shadow-xl backdrop-blur-md duration-400 fade-in slide-in-from-bottom-2", children: [
|
|
14980
15683
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-3.5 w-3.5 animate-spin text-(--chat-theme)" }),
|
|
14981
15684
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold uppercase tracking-[0.15em] text-(--chat-muted)", children: "Loading messages..." })
|
|
@@ -15599,10 +16302,10 @@ function useChannelMessageBox({
|
|
|
15599
16302
|
const composerDisabledReason = conversationId ? composerDisabledByConversation[conversationId] : void 0;
|
|
15600
16303
|
const fileInputRef = React2.useRef(null);
|
|
15601
16304
|
const attachmentsCountRef = React2.useRef(0);
|
|
15602
|
-
|
|
16305
|
+
React2__namespace.default.useEffect(() => {
|
|
15603
16306
|
attachmentsCountRef.current = state.attachments.length;
|
|
15604
16307
|
}, [state.attachments.length]);
|
|
15605
|
-
|
|
16308
|
+
React2__namespace.default.useEffect(() => {
|
|
15606
16309
|
const draft = {
|
|
15607
16310
|
messageInput: state.messageInput,
|
|
15608
16311
|
attachments: state.attachments
|
|
@@ -15610,7 +16313,7 @@ function useChannelMessageBox({
|
|
|
15610
16313
|
syncComposerRef(draft);
|
|
15611
16314
|
updateConversationDraft(conversationIdRef.current, draft);
|
|
15612
16315
|
}, [state.messageInput, state.attachments, syncComposerRef]);
|
|
15613
|
-
|
|
16316
|
+
React2__namespace.default.useEffect(() => {
|
|
15614
16317
|
if (typingTimeoutRef.current) {
|
|
15615
16318
|
clearTimeout(typingTimeoutRef.current);
|
|
15616
16319
|
typingTimeoutRef.current = null;
|
|
@@ -16161,10 +16864,10 @@ function useForwardModal({ isOpen, onClose, items, onForwardComplete }) {
|
|
|
16161
16864
|
targetChannelRef.current = channel;
|
|
16162
16865
|
const targetConversationIds = [String(channel.conversationId)];
|
|
16163
16866
|
items.forEach((item) => {
|
|
16164
|
-
const
|
|
16165
|
-
if (!
|
|
16867
|
+
const messageId2 = String(item.message._id || item.message.id || "");
|
|
16868
|
+
if (!messageId2) return;
|
|
16166
16869
|
const payload = {
|
|
16167
|
-
messageId,
|
|
16870
|
+
messageId: messageId2,
|
|
16168
16871
|
sender: String(loggedUserDetails._id),
|
|
16169
16872
|
sourceConversationId: item.message.conversationId ? String(item.message.conversationId) : void 0,
|
|
16170
16873
|
targetConversationIds,
|
|
@@ -16641,8 +17344,8 @@ var ChatMain = ({
|
|
|
16641
17344
|
viewportHeight = "full",
|
|
16642
17345
|
viewportClassName
|
|
16643
17346
|
}) => {
|
|
16644
|
-
const clientObj =
|
|
16645
|
-
const uiConfigObj =
|
|
17347
|
+
const clientObj = React2__namespace.default.useMemo(() => ({ id: clientId }), [clientId]);
|
|
17348
|
+
const uiConfigObj = React2__namespace.default.useMemo(
|
|
16646
17349
|
() => ({
|
|
16647
17350
|
...uiConfig || {},
|
|
16648
17351
|
components: { ...uiConfig?.components, ...components },
|
|
@@ -17077,6 +17780,8 @@ var packageDefaultComponents = {
|
|
|
17077
17780
|
// src/index.ts
|
|
17078
17781
|
var index_default = ChatMain_default;
|
|
17079
17782
|
|
|
17783
|
+
exports.Calendar = Calendar;
|
|
17784
|
+
exports.CalendarDayButton = CalendarDayButton;
|
|
17080
17785
|
exports.Channel = Channel;
|
|
17081
17786
|
exports.ChannelHeader = ChannelHeaderView_default;
|
|
17082
17787
|
exports.ChannelList = ChannelListView_default;
|
|
@@ -17085,6 +17790,7 @@ exports.Chat = Chat;
|
|
|
17085
17790
|
exports.ChatAlertsProvider = ChatAlertsProvider;
|
|
17086
17791
|
exports.ChatAvatar = ChatAvatar_default;
|
|
17087
17792
|
exports.ChatCustomizationProvider = ChatCustomizationProvider;
|
|
17793
|
+
exports.ChatDateJumpMenu = ChatDateJumpMenu;
|
|
17088
17794
|
exports.ChatLayout = ChatLayout_default;
|
|
17089
17795
|
exports.ChatLocaleProvider = ChatLocaleProvider;
|
|
17090
17796
|
exports.ChatMain = ChatMain_default;
|
|
@@ -17100,6 +17806,7 @@ exports.MessageInput = ChannelMessageBoxView_default;
|
|
|
17100
17806
|
exports.MessageItem = MessageItemView;
|
|
17101
17807
|
exports.MessageList = ActiveChannelMessagesView_default;
|
|
17102
17808
|
exports.capitalizeFirst = capitalizeFirst;
|
|
17809
|
+
exports.clampJumpDate = clampJumpDate;
|
|
17103
17810
|
exports.default = index_default;
|
|
17104
17811
|
exports.defaultChatClassNames = defaultChatClassNames;
|
|
17105
17812
|
exports.defaultChatComponents = defaultChatComponents;
|
|
@@ -17115,8 +17822,14 @@ exports.mergeChatLayoutConfig = mergeChatLayoutConfig;
|
|
|
17115
17822
|
exports.packageDefaultComponents = packageDefaultComponents;
|
|
17116
17823
|
exports.resolveApiUrl = resolveApiUrl;
|
|
17117
17824
|
exports.resolveChatApiKey = resolveChatApiKey;
|
|
17825
|
+
exports.resolveJumpDateBounds = resolveJumpDateBounds;
|
|
17826
|
+
exports.resolveJumpPreset = resolveJumpPreset;
|
|
17827
|
+
exports.resolveJumpStep = resolveJumpStep;
|
|
17118
17828
|
exports.resolveSocketUrl = resolveSocketUrl;
|
|
17119
17829
|
exports.showNotification = showNotification;
|
|
17830
|
+
exports.smoothScrollToMessage = smoothScrollToMessage;
|
|
17831
|
+
exports.startOfLocalDay = startOfLocalDay;
|
|
17832
|
+
exports.toDateInputValue = toDateInputValue;
|
|
17120
17833
|
exports.uniqueList = uniqueList;
|
|
17121
17834
|
exports.useChatAlerts = useChatAlerts;
|
|
17122
17835
|
exports.useChatContext = useChatContext;
|