@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.mjs
CHANGED
|
@@ -2,15 +2,17 @@ import { io } from 'socket.io-client';
|
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import { create } from 'zustand';
|
|
4
4
|
import { persist } from 'zustand/middleware';
|
|
5
|
-
import
|
|
5
|
+
import * as React2 from 'react';
|
|
6
|
+
import React2__default, { createContext, useMemo, useContext, useState, useCallback, useRef, useEffect, useLayoutEffect, useSyncExternalStore } from 'react';
|
|
6
7
|
import { Tooltip as Tooltip$1, Slot, Avatar as Avatar$1, ScrollArea as ScrollArea$1, Popover as Popover$1, DropdownMenu as DropdownMenu$1, Dialog as Dialog$1, Switch as Switch$1, AlertDialog as AlertDialog$1 } from 'radix-ui';
|
|
7
8
|
import { clsx } from 'clsx';
|
|
8
9
|
import { twMerge } from 'tailwind-merge';
|
|
9
10
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
10
11
|
import { flushSync } from 'react-dom';
|
|
11
|
-
import { Sun, Moon, Search, X, Loader2, UserPlus, ChevronDown, ArrowLeft, Users, WifiOff, Wifi, Sparkles, MessageSquareText, ChevronRight, Pin, Star, Phone, Video, MoreVertical, Info, UserKey, ShieldUser, Paperclip, Clock, MessageSquareX, Trash2, LogOut, Ban, CheckCheck, Check, Camera, Save, Pencil, Mail, CornerUpLeft, CheckSquare, Smile, MessageCircleMore, History, Shield, Send, AlertCircle, ShieldCheck, UserMinus, MessageCircle,
|
|
12
|
+
import { Sun, Moon, Search, X, Loader2, UserPlus, ChevronDown, ArrowLeft, Users, WifiOff, Wifi, Sparkles, MessageSquareText, ChevronRight, Pin, Star, Phone, Video, MoreVertical, Info, UserKey, ShieldUser, Paperclip, Clock, MessageSquareX, Trash2, LogOut, Ban, CheckCheck, Check, Camera, Save, Pencil, Mail, CornerUpLeft, CheckSquare, Smile, ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon, MessageCircleMore, History, Shield, Send, AlertCircle, ShieldCheck, UserMinus, MessageCircle, ExternalLink, Download, ChevronLeft, ZoomOut, ZoomIn, RotateCcw, Music, ArrowRight, MoreHorizontal, PinOff, StarOff, XIcon, ImageIcon, Film, Play, Pause, FileText, FileSpreadsheet, FileIcon, Eye, Captions } from 'lucide-react';
|
|
12
13
|
import { cva } from 'class-variance-authority';
|
|
13
14
|
import EmojiPicker, { Theme } from 'emoji-picker-react';
|
|
15
|
+
import { getDefaultClassNames, DayPicker } from 'react-day-picker';
|
|
14
16
|
import { toast } from 'react-hot-toast';
|
|
15
17
|
|
|
16
18
|
var __defProp = Object.defineProperty;
|
|
@@ -560,7 +562,7 @@ var init_message_helpers = __esm({
|
|
|
560
562
|
"src/store/helpers/message.helpers.ts"() {
|
|
561
563
|
getMessageSenderId = (message) => String(message?.sender?._id || message?.sender?.id || message?.senderId || message?.fromUserId || message?.sender || "");
|
|
562
564
|
extractMessageData = (payload) => {
|
|
563
|
-
const
|
|
565
|
+
const messageId2 = payload.messageId || payload._id || payload.message?._id || payload.message?.id;
|
|
564
566
|
const content = payload.content || payload.message?.content;
|
|
565
567
|
const conversationId = payload.conversationId || payload.conversation_id || payload.message?.conversationId || payload.message?.conversation_id;
|
|
566
568
|
const status = payload.status || payload.message?.status;
|
|
@@ -568,7 +570,7 @@ var init_message_helpers = __esm({
|
|
|
568
570
|
const isStarred = payload.isStarred ?? payload.message?.isStarred;
|
|
569
571
|
const attachmentId = payload.attachmentId || payload.unpinAttachmentId || null;
|
|
570
572
|
const caption = payload.caption ?? payload.message?.caption ?? null;
|
|
571
|
-
return { messageId, content, conversationId, status, isPinned, isStarred, attachmentId, caption };
|
|
573
|
+
return { messageId: messageId2, content, conversationId, status, isPinned, isStarred, attachmentId, caption };
|
|
572
574
|
};
|
|
573
575
|
statusRank = { sent: 0, delivered: 1, read: 2 };
|
|
574
576
|
preferHigherStatus = (base, incoming) => {
|
|
@@ -799,15 +801,15 @@ var init_conversation_helpers = __esm({
|
|
|
799
801
|
init_message_helpers();
|
|
800
802
|
init_participant_helpers();
|
|
801
803
|
init_unread_helpers();
|
|
802
|
-
findConversationIdByMessageId = (messagesByConversation,
|
|
804
|
+
findConversationIdByMessageId = (messagesByConversation, messageId2) => {
|
|
803
805
|
return Object.keys(messagesByConversation).find(
|
|
804
806
|
(cid) => messagesByConversation[cid].some(
|
|
805
|
-
(m) => String(m._id || m.id) === String(
|
|
807
|
+
(m) => String(m._id || m.id) === String(messageId2)
|
|
806
808
|
)
|
|
807
809
|
);
|
|
808
810
|
};
|
|
809
|
-
applyMessageStatusToStore = (state,
|
|
810
|
-
const normalizedMessageId = String(
|
|
811
|
+
applyMessageStatusToStore = (state, messageId2, status, conversationId) => {
|
|
812
|
+
const normalizedMessageId = String(messageId2);
|
|
811
813
|
const resolvedConversationId = conversationId ? String(conversationId) : findConversationIdByMessageId(state.messagesByConversation, normalizedMessageId) || findConversationIdByLastMessageId(state.conversations, normalizedMessageId) || null;
|
|
812
814
|
const nextConversations = state.conversations.map((conversation) => {
|
|
813
815
|
const lastMessageId = String(
|
|
@@ -850,6 +852,9 @@ var init_conversation_helpers = __esm({
|
|
|
850
852
|
const mergedParticipants = conversation.participants !== void 0 ? mergeConversationParticipants(existing?.participants, conversation.participants) : existing?.participants ?? conversation.participants;
|
|
851
853
|
const isGroup = isGroupConversation(conversation) || isGroupConversation(existing);
|
|
852
854
|
const resolvedGroupImage = resolveGroupImage(conversation) || resolveGroupImage(existing);
|
|
855
|
+
const incomingGroupName = typeof conversation.groupName === "string" && conversation.groupName.trim() || typeof conversation.name === "string" && conversation.name.trim() || "";
|
|
856
|
+
const existingGroupName = typeof existing?.groupName === "string" && existing.groupName.trim() || typeof existing?.name === "string" && existing.name.trim() || "";
|
|
857
|
+
const resolvedGroupName = incomingGroupName || existingGroupName || void 0;
|
|
853
858
|
return {
|
|
854
859
|
...existing,
|
|
855
860
|
...conversation,
|
|
@@ -857,7 +862,10 @@ var init_conversation_helpers = __esm({
|
|
|
857
862
|
isGroup,
|
|
858
863
|
isBlocked: resolvedBlocked,
|
|
859
864
|
lastMessage: mergeLastMessage(existing?.lastMessage, conversation.lastMessage),
|
|
860
|
-
...isGroup
|
|
865
|
+
...isGroup ? {
|
|
866
|
+
...resolvedGroupName ? { groupName: resolvedGroupName, name: resolvedGroupName } : {},
|
|
867
|
+
...resolvedGroupImage ? { image: resolvedGroupImage, groupImage: resolvedGroupImage } : {}
|
|
868
|
+
} : {}
|
|
861
869
|
};
|
|
862
870
|
};
|
|
863
871
|
resolveConversationLastMessage = (conversation, messagesByConversation) => {
|
|
@@ -929,9 +937,9 @@ var init_conversation_helpers = __esm({
|
|
|
929
937
|
if (!conversationId) return void 0;
|
|
930
938
|
return conversations.find((c) => String(c._id) === String(conversationId));
|
|
931
939
|
};
|
|
932
|
-
findConversationIdByLastMessageId = (conversations,
|
|
933
|
-
if (!
|
|
934
|
-
const normalizedMessageId = String(
|
|
940
|
+
findConversationIdByLastMessageId = (conversations, messageId2) => {
|
|
941
|
+
if (!messageId2) return null;
|
|
942
|
+
const normalizedMessageId = String(messageId2);
|
|
935
943
|
const match = conversations.find(
|
|
936
944
|
(conversation) => String(conversation?.lastMessage?._id || conversation?.lastMessage?.id || "") === normalizedMessageId
|
|
937
945
|
);
|
|
@@ -1350,7 +1358,7 @@ var init_api_constants = __esm({
|
|
|
1350
1358
|
ADD_REMOVE_MEMBERS: "/conversation/group/participants/add-remove",
|
|
1351
1359
|
ADD_REMOVE_ADMINS: "/conversation/group/admins/add-remove",
|
|
1352
1360
|
SEARCH_MESSAGES: "/message/search-messages",
|
|
1353
|
-
SEARCH_MESSAGES_CONTEXT: (
|
|
1361
|
+
SEARCH_MESSAGES_CONTEXT: (messageId2) => `/message/searched-message/context?messageId=${messageId2}`,
|
|
1354
1362
|
BLOCK_UNBLOCK_USER: "/user/block-unblock"
|
|
1355
1363
|
}
|
|
1356
1364
|
};
|
|
@@ -1494,9 +1502,9 @@ var init_messages_api = __esm({
|
|
|
1494
1502
|
throw error;
|
|
1495
1503
|
}
|
|
1496
1504
|
};
|
|
1497
|
-
searchMessagesContext = async (
|
|
1505
|
+
searchMessagesContext = async (messageId2) => {
|
|
1498
1506
|
try {
|
|
1499
|
-
const response = await apiClient.get(API_ENDPOINTS.GROUP.SEARCH_MESSAGES_CONTEXT(
|
|
1507
|
+
const response = await apiClient.get(API_ENDPOINTS.GROUP.SEARCH_MESSAGES_CONTEXT(messageId2));
|
|
1500
1508
|
return response.data;
|
|
1501
1509
|
} catch (error) {
|
|
1502
1510
|
console.error("Search messages context failed:", error);
|
|
@@ -1622,24 +1630,24 @@ var init_forwardPending_store = __esm({
|
|
|
1622
1630
|
"src/store/forwardPending.store.ts"() {
|
|
1623
1631
|
pendingForwards = /* @__PURE__ */ new Map();
|
|
1624
1632
|
lastPendingMessageId = null;
|
|
1625
|
-
setPendingForward = (
|
|
1626
|
-
if (!
|
|
1627
|
-
const key = String(
|
|
1633
|
+
setPendingForward = (messageId2, meta) => {
|
|
1634
|
+
if (!messageId2) return;
|
|
1635
|
+
const key = String(messageId2);
|
|
1628
1636
|
pendingForwards.set(key, meta);
|
|
1629
1637
|
lastPendingMessageId = key;
|
|
1630
1638
|
};
|
|
1631
|
-
peekPendingForward = (
|
|
1632
|
-
if (!
|
|
1633
|
-
return pendingForwards.get(String(
|
|
1639
|
+
peekPendingForward = (messageId2) => {
|
|
1640
|
+
if (!messageId2) return void 0;
|
|
1641
|
+
return pendingForwards.get(String(messageId2));
|
|
1634
1642
|
};
|
|
1635
1643
|
peekMostRecentPendingForward = () => {
|
|
1636
1644
|
if (!lastPendingMessageId) return void 0;
|
|
1637
1645
|
return pendingForwards.get(lastPendingMessageId);
|
|
1638
1646
|
};
|
|
1639
1647
|
getLastPendingForwardMessageId = () => lastPendingMessageId;
|
|
1640
|
-
clearPendingForward = (
|
|
1641
|
-
if (
|
|
1642
|
-
const key = String(
|
|
1648
|
+
clearPendingForward = (messageId2) => {
|
|
1649
|
+
if (messageId2) {
|
|
1650
|
+
const key = String(messageId2);
|
|
1643
1651
|
pendingForwards.delete(key);
|
|
1644
1652
|
if (lastPendingMessageId === key) lastPendingMessageId = null;
|
|
1645
1653
|
return;
|
|
@@ -2109,14 +2117,14 @@ var init_group_reaction_handlers = __esm({
|
|
|
2109
2117
|
return Array.from(map.values());
|
|
2110
2118
|
};
|
|
2111
2119
|
handleGroupReactionAddReceive = (set, get, payload) => {
|
|
2112
|
-
const
|
|
2120
|
+
const messageId2 = payload.messageId || payload._id;
|
|
2113
2121
|
const conversationId = payload.conversationId;
|
|
2114
|
-
if (!
|
|
2122
|
+
if (!messageId2) return;
|
|
2115
2123
|
set((state) => {
|
|
2116
|
-
const cid = conversationId || findConversationIdByMessageId(state.messagesByConversation,
|
|
2124
|
+
const cid = conversationId || findConversationIdByMessageId(state.messagesByConversation, messageId2);
|
|
2117
2125
|
if (!cid) return state;
|
|
2118
2126
|
const messages = state.messagesByConversation[cid] || [];
|
|
2119
|
-
const idx = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
2127
|
+
const idx = messages.findIndex((m) => String(m._id || m.id) === String(messageId2));
|
|
2120
2128
|
if (idx === -1) return state;
|
|
2121
2129
|
const nextMessages = [...messages];
|
|
2122
2130
|
const currentMsg = { ...nextMessages[idx] };
|
|
@@ -2134,20 +2142,20 @@ var init_group_reaction_handlers = __esm({
|
|
|
2134
2142
|
}
|
|
2135
2143
|
nextMessages[idx] = currentMsg;
|
|
2136
2144
|
return {
|
|
2137
|
-
lastReactionUpdate: { ...payload, messageId, action: "add", _v: Date.now() },
|
|
2145
|
+
lastReactionUpdate: { ...payload, messageId: messageId2, action: "add", _v: Date.now() },
|
|
2138
2146
|
messagesByConversation: { ...state.messagesByConversation, [cid]: nextMessages }
|
|
2139
2147
|
};
|
|
2140
2148
|
});
|
|
2141
2149
|
};
|
|
2142
2150
|
handleGroupReactionRemoveReceive = (set, get, payload) => {
|
|
2143
|
-
const
|
|
2151
|
+
const messageId2 = payload.messageId || payload._id;
|
|
2144
2152
|
const conversationId = payload.conversationId;
|
|
2145
|
-
if (!
|
|
2153
|
+
if (!messageId2) return;
|
|
2146
2154
|
set((state) => {
|
|
2147
|
-
const cid = conversationId || findConversationIdByMessageId(state.messagesByConversation,
|
|
2155
|
+
const cid = conversationId || findConversationIdByMessageId(state.messagesByConversation, messageId2);
|
|
2148
2156
|
if (!cid) return state;
|
|
2149
2157
|
const messages = state.messagesByConversation[cid] || [];
|
|
2150
|
-
const idx = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
2158
|
+
const idx = messages.findIndex((m) => String(m._id || m.id) === String(messageId2));
|
|
2151
2159
|
if (idx === -1) return state;
|
|
2152
2160
|
const nextMessages = [...messages];
|
|
2153
2161
|
const currentMsg = { ...nextMessages[idx] };
|
|
@@ -2164,7 +2172,7 @@ var init_group_reaction_handlers = __esm({
|
|
|
2164
2172
|
}
|
|
2165
2173
|
nextMessages[idx] = currentMsg;
|
|
2166
2174
|
return {
|
|
2167
|
-
lastReactionUpdate: { ...payload, messageId, action: "remove", _v: Date.now() },
|
|
2175
|
+
lastReactionUpdate: { ...payload, messageId: messageId2, action: "remove", _v: Date.now() },
|
|
2168
2176
|
messagesByConversation: { ...state.messagesByConversation, [cid]: nextMessages }
|
|
2169
2177
|
};
|
|
2170
2178
|
});
|
|
@@ -2194,14 +2202,14 @@ function removeMessageAttachment(message, attachmentId) {
|
|
|
2194
2202
|
if (attachments.length === message.attachments.length) return message;
|
|
2195
2203
|
return { ...message, attachments };
|
|
2196
2204
|
}
|
|
2197
|
-
function pinKey(
|
|
2198
|
-
return attachmentId ? `${
|
|
2205
|
+
function pinKey(messageId2, attachmentId) {
|
|
2206
|
+
return attachmentId ? `${messageId2}:${attachmentId}` : String(messageId2);
|
|
2199
2207
|
}
|
|
2200
|
-
function matchesPinEntry(entry,
|
|
2208
|
+
function matchesPinEntry(entry, messageId2, attachmentId) {
|
|
2201
2209
|
const entryMessageId = String(
|
|
2202
2210
|
entry?.messageId?._id || entry?.messageId || entry?._id || entry?.id || ""
|
|
2203
2211
|
);
|
|
2204
|
-
if (entryMessageId !== String(
|
|
2212
|
+
if (entryMessageId !== String(messageId2)) return false;
|
|
2205
2213
|
const entryAttachmentId = entry?.attachmentId ? String(entry.attachmentId) : null;
|
|
2206
2214
|
const targetAttachmentId = attachmentId ? String(attachmentId) : null;
|
|
2207
2215
|
return entryAttachmentId === targetAttachmentId;
|
|
@@ -2216,13 +2224,13 @@ function applyPinnedListToMessages(messages, pinnedMessage) {
|
|
|
2216
2224
|
)
|
|
2217
2225
|
);
|
|
2218
2226
|
return messages.map((message) => {
|
|
2219
|
-
const
|
|
2220
|
-
const hasWholeMessagePin = pinnedKeys.has(pinKey(
|
|
2227
|
+
const messageId2 = String(message._id || message.id);
|
|
2228
|
+
const hasWholeMessagePin = pinnedKeys.has(pinKey(messageId2, null));
|
|
2221
2229
|
const attachments = (message.attachments || []).map((att) => {
|
|
2222
2230
|
const attId = getAttachmentId(att);
|
|
2223
2231
|
return {
|
|
2224
2232
|
...att,
|
|
2225
|
-
isPinned: attId ? pinnedKeys.has(pinKey(
|
|
2233
|
+
isPinned: attId ? pinnedKeys.has(pinKey(messageId2, attId)) : !!att.isPinned
|
|
2226
2234
|
};
|
|
2227
2235
|
});
|
|
2228
2236
|
return {
|
|
@@ -2284,13 +2292,13 @@ var init_pin_handlers = __esm({
|
|
|
2284
2292
|
});
|
|
2285
2293
|
return;
|
|
2286
2294
|
}
|
|
2287
|
-
const { messageId, conversationId, isPinned, attachmentId } = extractMessageData(payload);
|
|
2288
|
-
if (!
|
|
2295
|
+
const { messageId: messageId2, conversationId, isPinned, attachmentId } = extractMessageData(payload);
|
|
2296
|
+
if (!messageId2 || !conversationId) return;
|
|
2289
2297
|
set((state) => {
|
|
2290
|
-
const sid = conversationId || findConversationIdByMessageId(state.messagesByConversation,
|
|
2298
|
+
const sid = conversationId || findConversationIdByMessageId(state.messagesByConversation, messageId2);
|
|
2291
2299
|
if (!sid) return state;
|
|
2292
2300
|
const messages = state.messagesByConversation[sid] || [];
|
|
2293
|
-
const index = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
2301
|
+
const index = messages.findIndex((m) => String(m._id || m.id) === String(messageId2));
|
|
2294
2302
|
let newMessagesByConversation = state.messagesByConversation;
|
|
2295
2303
|
const msg = index !== -1 ? messages[index] : null;
|
|
2296
2304
|
const wasPinned = attachmentId ? !!msg?.attachments?.some(
|
|
@@ -2312,9 +2320,9 @@ var init_pin_handlers = __esm({
|
|
|
2312
2320
|
const newPinnedByConv = { ...state.pinnedMessagesByConversation };
|
|
2313
2321
|
if (isPinned) {
|
|
2314
2322
|
const currentPinned = newPinnedByConv[sid] || [];
|
|
2315
|
-
if (!currentPinned.some((m) => matchesPinEntry(m,
|
|
2323
|
+
if (!currentPinned.some((m) => matchesPinEntry(m, messageId2, attachmentId || null))) {
|
|
2316
2324
|
const fullMsg = msg ? attachmentId ? {
|
|
2317
|
-
messageId,
|
|
2325
|
+
messageId: messageId2,
|
|
2318
2326
|
attachmentId,
|
|
2319
2327
|
attachment: msg.attachments?.find(
|
|
2320
2328
|
(att) => getAttachmentId(att) === String(attachmentId)
|
|
@@ -2326,7 +2334,7 @@ var init_pin_handlers = __esm({
|
|
|
2326
2334
|
}
|
|
2327
2335
|
} else {
|
|
2328
2336
|
newPinnedByConv[sid] = (newPinnedByConv[sid] || []).filter(
|
|
2329
|
-
(m) => !matchesPinEntry(m,
|
|
2337
|
+
(m) => !matchesPinEntry(m, messageId2, attachmentId || payload.unpinAttachmentId || null)
|
|
2330
2338
|
);
|
|
2331
2339
|
}
|
|
2332
2340
|
const conversation = get().conversations?.find((c) => String(c._id) === String(sid));
|
|
@@ -2341,8 +2349,8 @@ var init_pin_handlers = __esm({
|
|
|
2341
2349
|
pinnedCount = payload.totalCount;
|
|
2342
2350
|
}
|
|
2343
2351
|
const newPendingActions = { ...state.messagePendingActions };
|
|
2344
|
-
if (newPendingActions[
|
|
2345
|
-
delete newPendingActions[
|
|
2352
|
+
if (newPendingActions[messageId2]) {
|
|
2353
|
+
delete newPendingActions[messageId2];
|
|
2346
2354
|
}
|
|
2347
2355
|
return {
|
|
2348
2356
|
lastPinUpdate: payload,
|
|
@@ -2373,13 +2381,13 @@ var init_star_handlers = __esm({
|
|
|
2373
2381
|
init_attachment_helpers();
|
|
2374
2382
|
handleStarUpdate = (set, get, payload) => {
|
|
2375
2383
|
if (payload.starredBy && Array.isArray(payload.starredBy)) {
|
|
2376
|
-
const { messageId:
|
|
2384
|
+
const { messageId: messageId3, attachmentId } = extractMessageData(payload);
|
|
2377
2385
|
const { starredBy } = payload;
|
|
2378
|
-
if (!
|
|
2386
|
+
if (!messageId3) return;
|
|
2379
2387
|
set((state) => {
|
|
2380
|
-
const sid = payload.conversationId || findConversationIdByMessageId(state.messagesByConversation,
|
|
2388
|
+
const sid = payload.conversationId || findConversationIdByMessageId(state.messagesByConversation, messageId3);
|
|
2381
2389
|
const newPendingActions = { ...state.messagePendingActions };
|
|
2382
|
-
const pendingKey = String(
|
|
2390
|
+
const pendingKey = String(messageId3);
|
|
2383
2391
|
if (newPendingActions[pendingKey]) {
|
|
2384
2392
|
delete newPendingActions[pendingKey];
|
|
2385
2393
|
}
|
|
@@ -2389,7 +2397,7 @@ var init_star_handlers = __esm({
|
|
|
2389
2397
|
const loggedUserId = String(get().loggedUserDetails?._id || state.loggedUserDetails?._id || "");
|
|
2390
2398
|
const isStarred2 = starredBy.some((id) => String(id?._id || id) === loggedUserId) || loggedUserId === "" && starredBy.length > 0;
|
|
2391
2399
|
const messages = state.messagesByConversation[sid] || [];
|
|
2392
|
-
const index = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
2400
|
+
const index = messages.findIndex((m) => String(m._id || m.id) === String(messageId3));
|
|
2393
2401
|
let newMessagesByConversation = state.messagesByConversation;
|
|
2394
2402
|
if (index !== -1) {
|
|
2395
2403
|
const newMessages = [...messages];
|
|
@@ -2416,9 +2424,9 @@ var init_star_handlers = __esm({
|
|
|
2416
2424
|
const newStarredByConv = { ...state.starredMessagesByConversation };
|
|
2417
2425
|
const currentStarred = newStarredByConv[sid] || [];
|
|
2418
2426
|
const exists = attachmentId ? currentStarred.some(
|
|
2419
|
-
(m) => m.isAttachment && String(m.messageId) === String(
|
|
2427
|
+
(m) => m.isAttachment && String(m.messageId) === String(messageId3) && String(m.attachmentId) === String(attachmentId)
|
|
2420
2428
|
) : currentStarred.some(
|
|
2421
|
-
(m) => !m.isAttachment && String(m.messageId?._id || m.messageId || m._id || m.id) === String(
|
|
2429
|
+
(m) => !m.isAttachment && String(m.messageId?._id || m.messageId || m._id || m.id) === String(messageId3)
|
|
2422
2430
|
);
|
|
2423
2431
|
const conversation = get().conversations?.find((c) => String(c._id) === String(sid));
|
|
2424
2432
|
const existingCount = state.liveConversationCounts[sid]?.starredCount ?? conversation?.starredCount ?? 0;
|
|
@@ -2426,21 +2434,21 @@ var init_star_handlers = __esm({
|
|
|
2426
2434
|
if (isStarred2 && !exists) {
|
|
2427
2435
|
const fullMessage = attachmentId ? {
|
|
2428
2436
|
_id: attachmentId,
|
|
2429
|
-
messageId:
|
|
2437
|
+
messageId: messageId3,
|
|
2430
2438
|
attachmentId,
|
|
2431
2439
|
isAttachment: true,
|
|
2432
2440
|
attachment: index !== -1 ? newMessagesByConversation[sid][index]?.attachments?.find(
|
|
2433
2441
|
(att) => getAttachmentId(att) === String(attachmentId)
|
|
2434
2442
|
) : payload.attachment,
|
|
2435
2443
|
createdAt: payload.createdAt || (/* @__PURE__ */ new Date()).toISOString()
|
|
2436
|
-
} : index !== -1 ? newMessagesByConversation[sid][index] : { ...payload, _id:
|
|
2444
|
+
} : index !== -1 ? newMessagesByConversation[sid][index] : { ...payload, _id: messageId3 };
|
|
2437
2445
|
newStarredByConv[sid] = [...currentStarred, fullMessage];
|
|
2438
2446
|
starredCount = existingCount + 1;
|
|
2439
2447
|
} else if (!isStarred2 && exists) {
|
|
2440
2448
|
newStarredByConv[sid] = attachmentId ? currentStarred.filter(
|
|
2441
|
-
(m) => !(m.isAttachment && String(m.messageId) === String(
|
|
2449
|
+
(m) => !(m.isAttachment && String(m.messageId) === String(messageId3) && String(m.attachmentId) === String(attachmentId))
|
|
2442
2450
|
) : currentStarred.filter(
|
|
2443
|
-
(m) => String(m.messageId?._id || m.messageId || m._id || m.id) !== String(
|
|
2451
|
+
(m) => String(m.messageId?._id || m.messageId || m._id || m.id) !== String(messageId3)
|
|
2444
2452
|
);
|
|
2445
2453
|
starredCount = Math.max(0, existingCount - 1);
|
|
2446
2454
|
}
|
|
@@ -2466,13 +2474,13 @@ var init_star_handlers = __esm({
|
|
|
2466
2474
|
});
|
|
2467
2475
|
return;
|
|
2468
2476
|
}
|
|
2469
|
-
const { messageId, isStarred, conversationId } = extractMessageData(payload);
|
|
2470
|
-
if (!
|
|
2477
|
+
const { messageId: messageId2, isStarred, conversationId } = extractMessageData(payload);
|
|
2478
|
+
if (!messageId2) return;
|
|
2471
2479
|
set((state) => {
|
|
2472
|
-
const sid = conversationId || findConversationIdByMessageId(state.messagesByConversation,
|
|
2480
|
+
const sid = conversationId || findConversationIdByMessageId(state.messagesByConversation, messageId2);
|
|
2473
2481
|
if (!sid) return { lastStarUpdate: payload };
|
|
2474
2482
|
const messages = state.messagesByConversation[sid] || [];
|
|
2475
|
-
const index = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
2483
|
+
const index = messages.findIndex((m) => String(m._id || m.id) === String(messageId2));
|
|
2476
2484
|
let newMessagesByConversation = state.messagesByConversation;
|
|
2477
2485
|
const msg = index !== -1 ? messages[index] : null;
|
|
2478
2486
|
const wasStarred = msg ? !!msg.isStarred : false;
|
|
@@ -2488,13 +2496,13 @@ var init_star_handlers = __esm({
|
|
|
2488
2496
|
const newStarredByConv = { ...state.starredMessagesByConversation };
|
|
2489
2497
|
if (isStarred) {
|
|
2490
2498
|
const currentStarred = newStarredByConv[sid] || [];
|
|
2491
|
-
if (!currentStarred.some((m) => String(m?._id || m?.id || m.messageId?._id || m.messageId?.id) === String(
|
|
2499
|
+
if (!currentStarred.some((m) => String(m?._id || m?.id || m.messageId?._id || m.messageId?.id) === String(messageId2))) {
|
|
2492
2500
|
const fullMsg = msg ? { ...msg, isStarred: true } : payload;
|
|
2493
2501
|
newStarredByConv[sid] = [...currentStarred, fullMsg];
|
|
2494
2502
|
}
|
|
2495
2503
|
} else {
|
|
2496
2504
|
newStarredByConv[sid] = (newStarredByConv[sid] || []).filter(
|
|
2497
|
-
(m) => String(m?._id || m?.id || m.messageId?._id || m.messageId?.id) !== String(
|
|
2505
|
+
(m) => String(m?._id || m?.id || m.messageId?._id || m.messageId?.id) !== String(messageId2)
|
|
2498
2506
|
);
|
|
2499
2507
|
}
|
|
2500
2508
|
const conversation = get().conversations?.find((c) => String(c._id) === String(sid));
|
|
@@ -2509,7 +2517,7 @@ var init_star_handlers = __esm({
|
|
|
2509
2517
|
starredCount = payload.totalCount;
|
|
2510
2518
|
}
|
|
2511
2519
|
const newPendingActions = { ...state.messagePendingActions };
|
|
2512
|
-
const pendingKey = String(
|
|
2520
|
+
const pendingKey = String(messageId2);
|
|
2513
2521
|
if (newPendingActions[pendingKey]) {
|
|
2514
2522
|
delete newPendingActions[pendingKey];
|
|
2515
2523
|
}
|
|
@@ -2630,15 +2638,15 @@ var init_emit_actions = __esm({
|
|
|
2630
2638
|
socket_service_default.emit("dm_unpin", p);
|
|
2631
2639
|
},
|
|
2632
2640
|
emitDmStar: (p) => {
|
|
2633
|
-
const
|
|
2634
|
-
handleStarUpdate(set, get, { ...p, messageId, isStarred: true });
|
|
2635
|
-
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [
|
|
2641
|
+
const messageId2 = String(p.messageId);
|
|
2642
|
+
handleStarUpdate(set, get, { ...p, messageId: messageId2, isStarred: true });
|
|
2643
|
+
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [messageId2]: ["star"] } }));
|
|
2636
2644
|
socket_service_default.emit("dm_star", p);
|
|
2637
2645
|
},
|
|
2638
2646
|
emitDmUnstar: (p) => {
|
|
2639
|
-
const
|
|
2640
|
-
handleStarUpdate(set, get, { ...p, messageId, isStarred: false });
|
|
2641
|
-
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [
|
|
2647
|
+
const messageId2 = String(p.messageId);
|
|
2648
|
+
handleStarUpdate(set, get, { ...p, messageId: messageId2, isStarred: false });
|
|
2649
|
+
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [messageId2]: ["unstar"] } }));
|
|
2642
2650
|
socket_service_default.emit("dm_unstar", p);
|
|
2643
2651
|
},
|
|
2644
2652
|
emitDmForward: (p) => {
|
|
@@ -2690,15 +2698,15 @@ var init_emit_actions = __esm({
|
|
|
2690
2698
|
socket_service_default.emitGroupUnpin(p);
|
|
2691
2699
|
},
|
|
2692
2700
|
emitGroupStar: (p) => {
|
|
2693
|
-
const
|
|
2694
|
-
handleStarUpdate(set, get, { ...p, messageId, isStarred: true });
|
|
2695
|
-
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [
|
|
2701
|
+
const messageId2 = String(p.messageId);
|
|
2702
|
+
handleStarUpdate(set, get, { ...p, messageId: messageId2, isStarred: true });
|
|
2703
|
+
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [messageId2]: ["star"] } }));
|
|
2696
2704
|
socket_service_default.emitGroupStar(p);
|
|
2697
2705
|
},
|
|
2698
2706
|
emitGroupUnstar: (p) => {
|
|
2699
|
-
const
|
|
2700
|
-
handleStarUpdate(set, get, { ...p, messageId, isStarred: false });
|
|
2701
|
-
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [
|
|
2707
|
+
const messageId2 = String(p.messageId);
|
|
2708
|
+
handleStarUpdate(set, get, { ...p, messageId: messageId2, isStarred: false });
|
|
2709
|
+
set((state) => ({ messagePendingActions: { ...state.messagePendingActions, [messageId2]: ["unstar"] } }));
|
|
2702
2710
|
socket_service_default.emitGroupUnstar(p);
|
|
2703
2711
|
},
|
|
2704
2712
|
emitGroupForward: (p) => {
|
|
@@ -2717,8 +2725,8 @@ var init_emit_actions = __esm({
|
|
|
2717
2725
|
...p.attachmentId ? { attachmentId: String(p.attachmentId) } : {}
|
|
2718
2726
|
});
|
|
2719
2727
|
},
|
|
2720
|
-
clearForwardPending: (
|
|
2721
|
-
clearForwardPendingActions(set,
|
|
2728
|
+
clearForwardPending: (messageId2) => {
|
|
2729
|
+
clearForwardPendingActions(set, messageId2);
|
|
2722
2730
|
},
|
|
2723
2731
|
emitConversationUpdate: (p) => socket_service_default.emitConversationUpdate(p),
|
|
2724
2732
|
emitGroupLeave: (p) => socket_service_default.emitGroupLeave(p),
|
|
@@ -2743,7 +2751,7 @@ var init_message_handlers = __esm({
|
|
|
2743
2751
|
get().conversations,
|
|
2744
2752
|
loggedUserId
|
|
2745
2753
|
);
|
|
2746
|
-
const { messageId } = extractMessageData(lastDM);
|
|
2754
|
+
const { messageId: messageId2 } = extractMessageData(lastDM);
|
|
2747
2755
|
const tempId = lastDM.tempId;
|
|
2748
2756
|
const isFromSelf = loggedUserDetails && String(lastDM.sender?._id || lastDM.sender) === String(loggedUserDetails._id);
|
|
2749
2757
|
const activeConversationId = get().activeConversationId;
|
|
@@ -2753,14 +2761,14 @@ var init_message_handlers = __esm({
|
|
|
2753
2761
|
const newPendingActions = { ...state.messagePendingActions };
|
|
2754
2762
|
if (conversationId) {
|
|
2755
2763
|
const current = nextMessagesByConversation[conversationId] || [];
|
|
2756
|
-
let matchedId =
|
|
2764
|
+
let matchedId = messageId2;
|
|
2757
2765
|
if (tempId && state.messagePendingActions[tempId]) {
|
|
2758
2766
|
matchedId = tempId;
|
|
2759
2767
|
}
|
|
2760
|
-
const exists = current.some((m) => String(m._id || m.id) === String(
|
|
2768
|
+
const exists = current.some((m) => String(m._id || m.id) === String(messageId2));
|
|
2761
2769
|
if (matchedId && matchedId === tempId) {
|
|
2762
2770
|
nextMessagesByConversation[conversationId] = current.map(
|
|
2763
|
-
(m) => String(m.id || m._id) === String(matchedId) ? { ...m, _id:
|
|
2771
|
+
(m) => String(m.id || m._id) === String(matchedId) ? { ...m, _id: messageId2, id: messageId2, status: messageWithStatus.status } : m
|
|
2764
2772
|
);
|
|
2765
2773
|
delete newPendingActions[matchedId];
|
|
2766
2774
|
} else if (!exists) {
|
|
@@ -2793,8 +2801,7 @@ var init_message_handlers = __esm({
|
|
|
2793
2801
|
conversationType: lastDM.conversationType || "individual",
|
|
2794
2802
|
isGroup: false,
|
|
2795
2803
|
...shouldIncludeParticipants ? { participants: participantSeed } : {},
|
|
2796
|
-
groupName: lastDM.groupName,
|
|
2797
|
-
name: lastDM.groupName,
|
|
2804
|
+
...lastDM.groupName ? { groupName: lastDM.groupName, name: lastDM.groupName } : {},
|
|
2798
2805
|
owner: existingConv?.owner ?? lastDM.owner
|
|
2799
2806
|
},
|
|
2800
2807
|
{
|
|
@@ -2816,27 +2823,27 @@ var init_message_handlers = __esm({
|
|
|
2816
2823
|
}
|
|
2817
2824
|
};
|
|
2818
2825
|
handleEditDM = (set, get, payload) => {
|
|
2819
|
-
const { messageId, content, conversationId, attachmentId, caption } = extractMessageData(payload);
|
|
2820
|
-
if (!
|
|
2826
|
+
const { messageId: messageId2, content, conversationId, attachmentId, caption } = extractMessageData(payload);
|
|
2827
|
+
if (!messageId2) return;
|
|
2821
2828
|
const captionText = caption ?? content ?? "";
|
|
2822
2829
|
set((state) => {
|
|
2823
2830
|
let searchConversationId = conversationId;
|
|
2824
2831
|
if (!searchConversationId) {
|
|
2825
|
-
searchConversationId = findConversationIdByMessageId(state.messagesByConversation,
|
|
2832
|
+
searchConversationId = findConversationIdByMessageId(state.messagesByConversation, messageId2);
|
|
2826
2833
|
}
|
|
2827
2834
|
if (!searchConversationId) {
|
|
2828
2835
|
searchConversationId = state.conversations.find(
|
|
2829
|
-
(c) => String(c.lastMessage?._id || c.lastMessage?.id) === String(
|
|
2836
|
+
(c) => String(c.lastMessage?._id || c.lastMessage?.id) === String(messageId2)
|
|
2830
2837
|
)?._id;
|
|
2831
2838
|
}
|
|
2832
|
-
const normalizedEditPayload = { ...payload, messageId, content, conversationId: searchConversationId, _v: Date.now() };
|
|
2839
|
+
const normalizedEditPayload = { ...payload, messageId: messageId2, content, conversationId: searchConversationId, _v: Date.now() };
|
|
2833
2840
|
const newPendingActions = { ...state.messagePendingActions };
|
|
2834
|
-
if (newPendingActions[
|
|
2835
|
-
delete newPendingActions[
|
|
2841
|
+
if (newPendingActions[messageId2]) {
|
|
2842
|
+
delete newPendingActions[messageId2];
|
|
2836
2843
|
}
|
|
2837
2844
|
if (searchConversationId) {
|
|
2838
2845
|
const messages = state.messagesByConversation[searchConversationId] || [];
|
|
2839
|
-
const index = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
2846
|
+
const index = messages.findIndex((m) => String(m._id || m.id) === String(messageId2));
|
|
2840
2847
|
if (index !== -1) {
|
|
2841
2848
|
const newMessages = [...messages];
|
|
2842
2849
|
if (attachmentId) {
|
|
@@ -2862,15 +2869,15 @@ var init_message_handlers = __esm({
|
|
|
2862
2869
|
});
|
|
2863
2870
|
};
|
|
2864
2871
|
handleDeleteDM = (set, get, payload, type) => {
|
|
2865
|
-
const { messageId, conversationId, attachmentId } = extractMessageData(payload);
|
|
2866
|
-
if (!
|
|
2872
|
+
const { messageId: messageId2, conversationId, attachmentId } = extractMessageData(payload);
|
|
2873
|
+
if (!messageId2) return;
|
|
2867
2874
|
set((state) => {
|
|
2868
|
-
const searchConversationId = conversationId || findConversationIdByMessageId(state.messagesByConversation,
|
|
2875
|
+
const searchConversationId = conversationId || findConversationIdByMessageId(state.messagesByConversation, messageId2);
|
|
2869
2876
|
const messageTombstoned = payload.messageTombstoned === true;
|
|
2870
2877
|
let updatedConversations = state.conversations;
|
|
2871
2878
|
if (searchConversationId && !attachmentId) {
|
|
2872
2879
|
updatedConversations = state.conversations.map((c) => {
|
|
2873
|
-
if (String(c._id) === String(searchConversationId) && String(c.lastMessage?._id || c.lastMessage?.id) === String(
|
|
2880
|
+
if (String(c._id) === String(searchConversationId) && String(c.lastMessage?._id || c.lastMessage?.id) === String(messageId2)) {
|
|
2874
2881
|
return { ...c, lastMessage: type === "me" ? { ...c.lastMessage, content: "" } : { ...c.lastMessage, isDeletedForEveryone: true, content: "This message has been deleted" } };
|
|
2875
2882
|
}
|
|
2876
2883
|
return c;
|
|
@@ -2881,7 +2888,7 @@ var init_message_handlers = __esm({
|
|
|
2881
2888
|
if (searchConversationId) {
|
|
2882
2889
|
if (attachmentId) {
|
|
2883
2890
|
const updatedMessages = messages.map((m) => {
|
|
2884
|
-
if (String(m._id || m.id) !== String(
|
|
2891
|
+
if (String(m._id || m.id) !== String(messageId2)) return m;
|
|
2885
2892
|
if (messageTombstoned || type === "everyone" && payload.content) {
|
|
2886
2893
|
return {
|
|
2887
2894
|
...m,
|
|
@@ -2920,22 +2927,22 @@ var init_message_handlers = __esm({
|
|
|
2920
2927
|
[searchConversationId]: updatedMessages
|
|
2921
2928
|
};
|
|
2922
2929
|
} else if (type === "me") {
|
|
2923
|
-
nextMessagesByConversation = { ...state.messagesByConversation, [searchConversationId]: messages.filter((m) => String(m._id || m.id) !== String(
|
|
2930
|
+
nextMessagesByConversation = { ...state.messagesByConversation, [searchConversationId]: messages.filter((m) => String(m._id || m.id) !== String(messageId2)) };
|
|
2924
2931
|
} else {
|
|
2925
2932
|
nextMessagesByConversation = {
|
|
2926
2933
|
...state.messagesByConversation,
|
|
2927
|
-
[searchConversationId]: messages.map((m) => String(m._id || m.id) === String(
|
|
2934
|
+
[searchConversationId]: messages.map((m) => String(m._id || m.id) === String(messageId2) ? { ...m, isDeletedForEveryone: true, content: "" } : m)
|
|
2928
2935
|
};
|
|
2929
2936
|
}
|
|
2930
2937
|
}
|
|
2931
2938
|
const newPendingActions = { ...state.messagePendingActions };
|
|
2932
|
-
if (newPendingActions[
|
|
2933
|
-
delete newPendingActions[
|
|
2939
|
+
if (newPendingActions[messageId2]) {
|
|
2940
|
+
delete newPendingActions[messageId2];
|
|
2934
2941
|
}
|
|
2935
|
-
const shouldMarkWholeMessageDeleted = type === "me" && !attachmentId && !state.deletedForMeIds.includes(
|
|
2942
|
+
const shouldMarkWholeMessageDeleted = type === "me" && !attachmentId && !state.deletedForMeIds.includes(messageId2);
|
|
2936
2943
|
return {
|
|
2937
2944
|
lastDeleteDM: { ...payload, deleteType: type },
|
|
2938
|
-
deletedForMeIds: shouldMarkWholeMessageDeleted ? [...state.deletedForMeIds,
|
|
2945
|
+
deletedForMeIds: shouldMarkWholeMessageDeleted ? [...state.deletedForMeIds, messageId2] : state.deletedForMeIds,
|
|
2939
2946
|
messagesByConversation: nextMessagesByConversation,
|
|
2940
2947
|
conversations: updatedConversations,
|
|
2941
2948
|
messagePendingActions: newPendingActions
|
|
@@ -3009,15 +3016,15 @@ var init_dm_actions = __esm({
|
|
|
3009
3016
|
},
|
|
3010
3017
|
receivedStatusUpdate: (payload) => {
|
|
3011
3018
|
const data = extractMessageData(payload);
|
|
3012
|
-
const { messageId, status } = data;
|
|
3019
|
+
const { messageId: messageId2, status } = data;
|
|
3013
3020
|
let { conversationId } = data;
|
|
3014
|
-
if (!
|
|
3021
|
+
if (!messageId2 || !status) return;
|
|
3015
3022
|
set({ lastStatusUpdate: payload });
|
|
3016
3023
|
if (!conversationId) {
|
|
3017
|
-
conversationId = findConversationIdByMessageId(get().messagesByConversation,
|
|
3024
|
+
conversationId = findConversationIdByMessageId(get().messagesByConversation, messageId2) || findConversationIdByLastMessageId(get().conversations, messageId2) || void 0;
|
|
3018
3025
|
}
|
|
3019
3026
|
set((state) => ({
|
|
3020
|
-
...applyMessageStatusToStore(state, String(
|
|
3027
|
+
...applyMessageStatusToStore(state, String(messageId2), status, conversationId)
|
|
3021
3028
|
}));
|
|
3022
3029
|
},
|
|
3023
3030
|
receivedDMMarkRead: (payload) => {
|
|
@@ -3074,7 +3081,7 @@ var init_group_handlers = __esm({
|
|
|
3074
3081
|
get().conversations,
|
|
3075
3082
|
loggedUserId
|
|
3076
3083
|
);
|
|
3077
|
-
const { messageId } = extractMessageData(lastDM);
|
|
3084
|
+
const { messageId: messageId2 } = extractMessageData(lastDM);
|
|
3078
3085
|
const tempId = lastDM.tempId;
|
|
3079
3086
|
const activeConversationId = get().activeConversationId;
|
|
3080
3087
|
const isOpenConversation = conversationId && String(conversationId) === String(activeConversationId);
|
|
@@ -3111,23 +3118,23 @@ var init_group_handlers = __esm({
|
|
|
3111
3118
|
);
|
|
3112
3119
|
if (optimisticMsg) matchedTempId = optimisticMsg.id;
|
|
3113
3120
|
}
|
|
3114
|
-
const messageExists = current.some((m) => String(m._id || m.id) === String(
|
|
3121
|
+
const messageExists = current.some((m) => String(m._id || m.id) === String(messageId2));
|
|
3115
3122
|
if (!messageExists) {
|
|
3116
3123
|
nextMessagesByConversation[conversationId] = [...current, {
|
|
3117
3124
|
...lastDM,
|
|
3118
|
-
_id:
|
|
3119
|
-
id:
|
|
3125
|
+
_id: messageId2,
|
|
3126
|
+
id: messageId2,
|
|
3120
3127
|
status: lastDM.status || "sent"
|
|
3121
3128
|
}];
|
|
3122
3129
|
} else {
|
|
3123
3130
|
nextMessagesByConversation[conversationId] = current.map(
|
|
3124
|
-
(m) => String(m._id || m.id) === String(
|
|
3131
|
+
(m) => String(m._id || m.id) === String(messageId2) ? { ...m, status: lastDM.status || "sent" } : m
|
|
3125
3132
|
);
|
|
3126
3133
|
}
|
|
3127
3134
|
if (matchedTempId) {
|
|
3128
3135
|
delete newPendingActions[matchedTempId];
|
|
3129
3136
|
nextMessagesByConversation[conversationId] = nextMessagesByConversation[conversationId].map(
|
|
3130
|
-
(m) => String(m.id || m._id) === String(matchedTempId) ? { ...m, _id:
|
|
3137
|
+
(m) => String(m.id || m._id) === String(matchedTempId) ? { ...m, _id: messageId2, id: messageId2, status: lastDM.status || "sent" } : m
|
|
3131
3138
|
);
|
|
3132
3139
|
}
|
|
3133
3140
|
}
|
|
@@ -3137,8 +3144,10 @@ var init_group_handlers = __esm({
|
|
|
3137
3144
|
_id: conversationId,
|
|
3138
3145
|
conversationType: "group",
|
|
3139
3146
|
isGroup: true,
|
|
3140
|
-
groupName
|
|
3141
|
-
|
|
3147
|
+
...lastDM.groupName || lastDM.name ? {
|
|
3148
|
+
groupName: lastDM.groupName || lastDM.name,
|
|
3149
|
+
name: lastDM.groupName || lastDM.name
|
|
3150
|
+
} : {},
|
|
3142
3151
|
participants: buildParticipantsFromMessagePayload(lastDM, loggedUserId)
|
|
3143
3152
|
},
|
|
3144
3153
|
{
|
|
@@ -3176,8 +3185,10 @@ var init_group_handlers = __esm({
|
|
|
3176
3185
|
_id: conversationId,
|
|
3177
3186
|
conversationType: "group",
|
|
3178
3187
|
isGroup: true,
|
|
3179
|
-
groupName
|
|
3180
|
-
|
|
3188
|
+
...lastDM.groupName || lastDM.name ? {
|
|
3189
|
+
groupName: lastDM.groupName || lastDM.name,
|
|
3190
|
+
name: lastDM.groupName || lastDM.name
|
|
3191
|
+
} : {},
|
|
3181
3192
|
participants: buildParticipantsFromMessagePayload(lastDM, loggedUserId)
|
|
3182
3193
|
},
|
|
3183
3194
|
{
|
|
@@ -3196,10 +3207,10 @@ var init_group_handlers = __esm({
|
|
|
3196
3207
|
(c) => String(c._id) === String(conversationId)
|
|
3197
3208
|
);
|
|
3198
3209
|
const isGroupChat = isGroupConversation(targetConv);
|
|
3199
|
-
if (loggedUserDetails?._id &&
|
|
3210
|
+
if (loggedUserDetails?._id && messageId2 && isGroupChat) {
|
|
3200
3211
|
get().emitGroupMessageDelivered({
|
|
3201
3212
|
conversationId,
|
|
3202
|
-
messageId,
|
|
3213
|
+
messageId: messageId2,
|
|
3203
3214
|
userId: loggedUserDetails._id
|
|
3204
3215
|
});
|
|
3205
3216
|
}
|
|
@@ -3277,15 +3288,15 @@ var init_group_actions2 = __esm({
|
|
|
3277
3288
|
receivedGroupStatusUpdate: (payload) => {
|
|
3278
3289
|
const data = extractMessageData(payload);
|
|
3279
3290
|
let { conversationId } = data;
|
|
3280
|
-
const { messageId, status } = data;
|
|
3291
|
+
const { messageId: messageId2, status } = data;
|
|
3281
3292
|
set({ lastStatusUpdate: payload });
|
|
3282
3293
|
if (!status) return;
|
|
3283
|
-
if (
|
|
3294
|
+
if (messageId2) {
|
|
3284
3295
|
if (!conversationId) {
|
|
3285
|
-
conversationId = findConversationIdByMessageId(get().messagesByConversation,
|
|
3296
|
+
conversationId = findConversationIdByMessageId(get().messagesByConversation, messageId2) || findConversationIdByLastMessageId(get().conversations, messageId2) || void 0;
|
|
3286
3297
|
}
|
|
3287
3298
|
set((state) => ({
|
|
3288
|
-
...applyMessageStatusToStore(state, String(
|
|
3299
|
+
...applyMessageStatusToStore(state, String(messageId2), status, conversationId)
|
|
3289
3300
|
}));
|
|
3290
3301
|
return;
|
|
3291
3302
|
}
|
|
@@ -3501,7 +3512,7 @@ var init_receive = __esm({
|
|
|
3501
3512
|
};
|
|
3502
3513
|
});
|
|
3503
3514
|
},
|
|
3504
|
-
markDeletedForMe: (
|
|
3515
|
+
markDeletedForMe: (messageId2) => set((state) => ({ deletedForMeIds: [...state.deletedForMeIds, messageId2] }))
|
|
3505
3516
|
});
|
|
3506
3517
|
createReceiveActions = (set, get) => ({
|
|
3507
3518
|
...createDmReceiveActions(set, get),
|
|
@@ -3526,13 +3537,13 @@ var init_search_actions = __esm({
|
|
|
3526
3537
|
init_api_service();
|
|
3527
3538
|
init_store_helpers();
|
|
3528
3539
|
createSearchActions = (set, _get) => ({
|
|
3529
|
-
fetchSearchMessageContext: async (
|
|
3540
|
+
fetchSearchMessageContext: async (messageId2, options) => {
|
|
3530
3541
|
const searchMode = options?.searchMode !== false;
|
|
3531
|
-
set({ isSearchActive: searchMode, searchedMessageId:
|
|
3542
|
+
set({ isSearchActive: searchMode, searchedMessageId: messageId2, isFetchingMessages: true });
|
|
3532
3543
|
try {
|
|
3533
|
-
const response = await searchMessagesContext(
|
|
3544
|
+
const response = await searchMessagesContext(messageId2);
|
|
3534
3545
|
const data = response.data?.list || response.data?.messages || response.messages || response.data || [];
|
|
3535
|
-
const highlightId = response.data?.highlightMessageId ||
|
|
3546
|
+
const highlightId = response.data?.highlightMessageId || messageId2;
|
|
3536
3547
|
if (data.length > 0) {
|
|
3537
3548
|
const conversationId = data[0].conversationId;
|
|
3538
3549
|
if (conversationId) {
|
|
@@ -3561,7 +3572,7 @@ var init_search_actions = __esm({
|
|
|
3561
3572
|
}
|
|
3562
3573
|
},
|
|
3563
3574
|
setSearchActive: (active) => set({ isSearchActive: active }),
|
|
3564
|
-
setSearchedMessageId: (
|
|
3575
|
+
setSearchedMessageId: (messageId2) => set({ searchedMessageId: messageId2 })
|
|
3565
3576
|
});
|
|
3566
3577
|
}
|
|
3567
3578
|
});
|
|
@@ -3928,6 +3939,7 @@ var buildIncomingMessageFromDM = (lastDM, loggedUserId, conversations) => {
|
|
|
3928
3939
|
content: lastDM.content || lastDM.message?.content || "",
|
|
3929
3940
|
sender: lastDM.sender?.name || lastDM.fromUserId || (isMe ? "Me" : "User"),
|
|
3930
3941
|
senderId: String(lastDM.sender?._id || lastDM.sender || lastDM.fromUserId || ""),
|
|
3942
|
+
senderImage: lastDM.sender?.image,
|
|
3931
3943
|
timestamp: lastDM.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
3932
3944
|
isOwnMessage: isMe,
|
|
3933
3945
|
channelId,
|
|
@@ -4085,9 +4097,9 @@ var syncLocalMessagesOnPinUpdate = (prev, lastPinUpdate) => {
|
|
|
4085
4097
|
return next;
|
|
4086
4098
|
};
|
|
4087
4099
|
var syncLocalMessagesOnStarUpdate = (prev, lastStarUpdate, loggedUserId) => {
|
|
4088
|
-
const
|
|
4089
|
-
if (!
|
|
4090
|
-
const mid = String(
|
|
4100
|
+
const messageId2 = lastStarUpdate.messageId || lastStarUpdate._id;
|
|
4101
|
+
if (!messageId2) return null;
|
|
4102
|
+
const mid = String(messageId2);
|
|
4091
4103
|
let isStarred;
|
|
4092
4104
|
if (typeof lastStarUpdate.isStarred === "boolean") {
|
|
4093
4105
|
isStarred = lastStarUpdate.isStarred;
|
|
@@ -4106,9 +4118,9 @@ var syncLocalMessagesOnStarUpdate = (prev, lastStarUpdate, loggedUserId) => {
|
|
|
4106
4118
|
return next;
|
|
4107
4119
|
};
|
|
4108
4120
|
var syncLocalMessagesOnReactionUpdate = (prev, lastReactionUpdate, messagesByConversation) => {
|
|
4109
|
-
const
|
|
4110
|
-
if (!
|
|
4111
|
-
const mid = String(
|
|
4121
|
+
const messageId2 = lastReactionUpdate.messageId || lastReactionUpdate._id;
|
|
4122
|
+
if (!messageId2) return prev;
|
|
4123
|
+
const mid = String(messageId2);
|
|
4112
4124
|
let storeReactions;
|
|
4113
4125
|
for (const msgs of Object.values(messagesByConversation)) {
|
|
4114
4126
|
const found = msgs.find((m) => String(m._id || m.id) === mid);
|
|
@@ -4159,7 +4171,7 @@ var syncLocalMessagesOnReactionUpdate = (prev, lastReactionUpdate, messagesByCon
|
|
|
4159
4171
|
return changed ? next : prev;
|
|
4160
4172
|
};
|
|
4161
4173
|
var syncLocalMessagesOnDelete = (prev, lastDeleteDM) => {
|
|
4162
|
-
const
|
|
4174
|
+
const messageId2 = lastDeleteDM.messageId || lastDeleteDM._id;
|
|
4163
4175
|
const deleteType = lastDeleteDM.deleteType || "everyone";
|
|
4164
4176
|
const attachmentId = lastDeleteDM.attachmentId ? String(lastDeleteDM.attachmentId) : null;
|
|
4165
4177
|
const messageTombstoned = lastDeleteDM.messageTombstoned === true;
|
|
@@ -4167,7 +4179,7 @@ var syncLocalMessagesOnDelete = (prev, lastDeleteDM) => {
|
|
|
4167
4179
|
Object.keys(next).forEach((channelId) => {
|
|
4168
4180
|
if (attachmentId) {
|
|
4169
4181
|
next[channelId] = next[channelId].map((message) => {
|
|
4170
|
-
if (String(message._id || message.id) !== String(
|
|
4182
|
+
if (String(message._id || message.id) !== String(messageId2)) {
|
|
4171
4183
|
return message;
|
|
4172
4184
|
}
|
|
4173
4185
|
return applyLocalAttachmentDelete(
|
|
@@ -4181,26 +4193,26 @@ var syncLocalMessagesOnDelete = (prev, lastDeleteDM) => {
|
|
|
4181
4193
|
}
|
|
4182
4194
|
if (deleteType === "me") {
|
|
4183
4195
|
next[channelId] = next[channelId].filter(
|
|
4184
|
-
(m) => String(m._id || m.id) !== String(
|
|
4196
|
+
(m) => String(m._id || m.id) !== String(messageId2)
|
|
4185
4197
|
);
|
|
4186
4198
|
} else {
|
|
4187
4199
|
next[channelId] = next[channelId].map(
|
|
4188
|
-
(m) => String(m._id || m.id) === String(
|
|
4200
|
+
(m) => String(m._id || m.id) === String(messageId2) ? { ...m, isDeletedForEveryone: true } : m
|
|
4189
4201
|
);
|
|
4190
4202
|
}
|
|
4191
4203
|
});
|
|
4192
4204
|
return next;
|
|
4193
4205
|
};
|
|
4194
4206
|
var syncLocalMessagesOnEdit = (prev, lastEditDM) => {
|
|
4195
|
-
const
|
|
4207
|
+
const messageId2 = lastEditDM.messageId || lastEditDM._id;
|
|
4196
4208
|
const content = lastEditDM.content;
|
|
4197
4209
|
const attachmentId = lastEditDM.attachmentId ? String(lastEditDM.attachmentId) : null;
|
|
4198
4210
|
const caption = lastEditDM.caption ?? content;
|
|
4199
|
-
if (!
|
|
4211
|
+
if (!messageId2) return null;
|
|
4200
4212
|
const next = { ...prev };
|
|
4201
4213
|
Object.keys(next).forEach((channelId) => {
|
|
4202
4214
|
const messages = next[channelId];
|
|
4203
|
-
const index = messages.findIndex((m) => String(m._id || m.id) === String(
|
|
4215
|
+
const index = messages.findIndex((m) => String(m._id || m.id) === String(messageId2));
|
|
4204
4216
|
if (index !== -1) {
|
|
4205
4217
|
const updated = [...messages];
|
|
4206
4218
|
const current = updated[index];
|
|
@@ -4470,7 +4482,7 @@ var Chat = ({
|
|
|
4470
4482
|
const status = useStore((s) => s.status);
|
|
4471
4483
|
const error = useStore((s) => s.error);
|
|
4472
4484
|
useChatSync();
|
|
4473
|
-
|
|
4485
|
+
React2__default.useEffect(() => {
|
|
4474
4486
|
const clientId = client?.id;
|
|
4475
4487
|
const initializeChat = async () => {
|
|
4476
4488
|
if (!clientId || !loggedUserDetails) return;
|
|
@@ -4559,28 +4571,28 @@ var Chat = ({
|
|
|
4559
4571
|
queryParamApis: queryParamApis ?? ["get"],
|
|
4560
4572
|
queryParamsByApi: queryParamsByApi ?? {}
|
|
4561
4573
|
});
|
|
4562
|
-
|
|
4574
|
+
React2__default.useEffect(() => {
|
|
4563
4575
|
setChatQueryParams(queryParams);
|
|
4564
4576
|
setChatQueryParamApis(queryParamApis);
|
|
4565
4577
|
setChatQueryParamsByApi(queryParamsByApi);
|
|
4566
4578
|
}, [queryConfigKey]);
|
|
4567
|
-
|
|
4579
|
+
React2__default.useEffect(() => {
|
|
4568
4580
|
if (lastDM && onMessageReceived) {
|
|
4569
4581
|
onMessageReceived(lastDM);
|
|
4570
4582
|
}
|
|
4571
4583
|
}, [lastDM, onMessageReceived]);
|
|
4572
|
-
|
|
4584
|
+
React2__default.useEffect(() => {
|
|
4573
4585
|
if (status === "connected" && onSocketConnected) {
|
|
4574
4586
|
const socketId = useStore.getState().socketId;
|
|
4575
4587
|
if (socketId) onSocketConnected(socketId);
|
|
4576
4588
|
}
|
|
4577
4589
|
}, [status, onSocketConnected]);
|
|
4578
|
-
|
|
4590
|
+
React2__default.useEffect(() => {
|
|
4579
4591
|
if (status === "error" && error && onSocketError) {
|
|
4580
4592
|
onSocketError(error);
|
|
4581
4593
|
}
|
|
4582
4594
|
}, [status, error, onSocketError]);
|
|
4583
|
-
const contextValue =
|
|
4595
|
+
const contextValue = React2__default.useMemo(
|
|
4584
4596
|
() => ({
|
|
4585
4597
|
onSendMessage,
|
|
4586
4598
|
client,
|
|
@@ -4600,7 +4612,7 @@ var Chat = ({
|
|
|
4600
4612
|
messagesData
|
|
4601
4613
|
]
|
|
4602
4614
|
);
|
|
4603
|
-
const customization =
|
|
4615
|
+
const customization = React2__default.useMemo(
|
|
4604
4616
|
() => ({
|
|
4605
4617
|
components: uiConfig.components,
|
|
4606
4618
|
classNames: uiConfig.classNames,
|
|
@@ -6695,20 +6707,35 @@ init_chat_constants();
|
|
|
6695
6707
|
// src/chat/lib/last-message-preview.ts
|
|
6696
6708
|
init_store_helpers();
|
|
6697
6709
|
|
|
6698
|
-
// src/chat/lib/
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6710
|
+
// src/chat/lib/attachment-preview-labels.ts
|
|
6711
|
+
function getAttachmentTypePreviewLabel(type) {
|
|
6712
|
+
switch (String(type || "").toLowerCase()) {
|
|
6713
|
+
case "image":
|
|
6714
|
+
return "Photo";
|
|
6715
|
+
case "video":
|
|
6716
|
+
return "Video";
|
|
6717
|
+
case "audio":
|
|
6718
|
+
return "Audio";
|
|
6719
|
+
case "file":
|
|
6720
|
+
case "document":
|
|
6721
|
+
case "spreadsheet":
|
|
6722
|
+
return "Attachment";
|
|
6723
|
+
default:
|
|
6724
|
+
return "Attachment";
|
|
6707
6725
|
}
|
|
6708
|
-
|
|
6709
|
-
|
|
6726
|
+
}
|
|
6727
|
+
function getAttachmentCountPreviewLabel(type, count) {
|
|
6728
|
+
if (count <= 1) return getAttachmentTypePreviewLabel(type);
|
|
6729
|
+
switch (String(type).toLowerCase()) {
|
|
6730
|
+
case "image":
|
|
6731
|
+
return `${count} photos`;
|
|
6732
|
+
case "video":
|
|
6733
|
+
return `${count} videos`;
|
|
6734
|
+
case "audio":
|
|
6735
|
+
return `${count} audio files`;
|
|
6736
|
+
default:
|
|
6737
|
+
return `${count} attachments`;
|
|
6710
6738
|
}
|
|
6711
|
-
return name.trim() || trimmed;
|
|
6712
6739
|
}
|
|
6713
6740
|
|
|
6714
6741
|
// src/chat/lib/last-message-preview.ts
|
|
@@ -6716,21 +6743,30 @@ function getAttachmentOnlyPreviewText(attachments) {
|
|
|
6716
6743
|
const images = attachments.filter((att2) => att2.type === "image" && att2.url);
|
|
6717
6744
|
const videos = attachments.filter((att2) => att2.type === "video" && att2.url);
|
|
6718
6745
|
const audios = attachments.filter((att2) => att2.type === "audio" && att2.url);
|
|
6719
|
-
|
|
6746
|
+
const files = attachments.filter(
|
|
6747
|
+
(att2) => att2.url && !["image", "video", "audio"].includes(att2.type)
|
|
6748
|
+
);
|
|
6749
|
+
if (images.length > 1) return getAttachmentCountPreviewLabel("image", images.length);
|
|
6720
6750
|
if (images.length === 1) {
|
|
6721
|
-
return images[0].caption?.trim() || "
|
|
6751
|
+
return images[0].caption?.trim() || getAttachmentTypePreviewLabel("image");
|
|
6722
6752
|
}
|
|
6723
|
-
if (videos.length > 1) return
|
|
6753
|
+
if (videos.length > 1) return getAttachmentCountPreviewLabel("video", videos.length);
|
|
6724
6754
|
if (videos.length === 1) {
|
|
6725
|
-
return videos[0].caption?.trim() || "
|
|
6755
|
+
return videos[0].caption?.trim() || getAttachmentTypePreviewLabel("video");
|
|
6726
6756
|
}
|
|
6727
|
-
if (audios.length > 1) return
|
|
6757
|
+
if (audios.length > 1) return getAttachmentCountPreviewLabel("audio", audios.length);
|
|
6728
6758
|
if (audios.length === 1) {
|
|
6729
|
-
return audios[0].caption?.trim() || "
|
|
6759
|
+
return audios[0].caption?.trim() || getAttachmentTypePreviewLabel("audio");
|
|
6760
|
+
}
|
|
6761
|
+
if (files.length > 1) return getAttachmentCountPreviewLabel("file", files.length);
|
|
6762
|
+
if (files.length === 1) {
|
|
6763
|
+
return files[0].caption?.trim() || getAttachmentTypePreviewLabel(files[0].type);
|
|
6764
|
+
}
|
|
6765
|
+
if (attachments.length > 1) {
|
|
6766
|
+
return getAttachmentCountPreviewLabel("file", attachments.length);
|
|
6730
6767
|
}
|
|
6731
|
-
if (attachments.length > 1) return `${attachments.length} files`;
|
|
6732
6768
|
const att = attachments[0];
|
|
6733
|
-
return att
|
|
6769
|
+
return att?.caption?.trim() || getAttachmentTypePreviewLabel(att?.type);
|
|
6734
6770
|
}
|
|
6735
6771
|
function getLastMessageSidebarPreview(message) {
|
|
6736
6772
|
const content = String(message?.content || "").trim();
|
|
@@ -6744,6 +6780,10 @@ function getLastMessageSidebarPreview(message) {
|
|
|
6744
6780
|
if (attachments.length > 0) {
|
|
6745
6781
|
return getAttachmentOnlyPreviewText(attachments);
|
|
6746
6782
|
}
|
|
6783
|
+
const messageType = String(message?.type || "").toLowerCase();
|
|
6784
|
+
if (messageType && messageType !== "text") {
|
|
6785
|
+
return getAttachmentTypePreviewLabel(messageType);
|
|
6786
|
+
}
|
|
6747
6787
|
return "No messages yet";
|
|
6748
6788
|
}
|
|
6749
6789
|
function getMessagePreviewText(message, fallback = "Message") {
|
|
@@ -6755,6 +6795,10 @@ function getMessagePreviewText(message, fallback = "Message") {
|
|
|
6755
6795
|
if (attachments.length > 0) {
|
|
6756
6796
|
return getAttachmentOnlyPreviewText(attachments);
|
|
6757
6797
|
}
|
|
6798
|
+
const messageType = String(message?.type || "").toLowerCase();
|
|
6799
|
+
if (messageType && messageType !== "text") {
|
|
6800
|
+
return getAttachmentTypePreviewLabel(messageType);
|
|
6801
|
+
}
|
|
6758
6802
|
return fallback;
|
|
6759
6803
|
}
|
|
6760
6804
|
|
|
@@ -7396,7 +7440,7 @@ function highlightSearchMatch(text, query) {
|
|
|
7396
7440
|
children: part
|
|
7397
7441
|
},
|
|
7398
7442
|
`${part}-${index}`
|
|
7399
|
-
) : /* @__PURE__ */ jsx(
|
|
7443
|
+
) : /* @__PURE__ */ jsx(React2__default.Fragment, { children: part }, `${part}-${index}`)
|
|
7400
7444
|
);
|
|
7401
7445
|
}
|
|
7402
7446
|
function getMessagePreview(message) {
|
|
@@ -7811,11 +7855,11 @@ function buildAttachmentSummary(attachments) {
|
|
|
7811
7855
|
else fileCount += 1;
|
|
7812
7856
|
}
|
|
7813
7857
|
const parts = [];
|
|
7814
|
-
if (imageCount) parts.push(
|
|
7815
|
-
if (videoCount) parts.push(
|
|
7816
|
-
if (audioCount) parts.push(
|
|
7817
|
-
if (fileCount) parts.push(
|
|
7818
|
-
return parts.join(", ") || "
|
|
7858
|
+
if (imageCount) parts.push(getAttachmentCountPreviewLabel("image", imageCount));
|
|
7859
|
+
if (videoCount) parts.push(getAttachmentCountPreviewLabel("video", videoCount));
|
|
7860
|
+
if (audioCount) parts.push(getAttachmentCountPreviewLabel("audio", audioCount));
|
|
7861
|
+
if (fileCount) parts.push(getAttachmentCountPreviewLabel("file", fileCount));
|
|
7862
|
+
return parts.join(", ") || getAttachmentTypePreviewLabel("file");
|
|
7819
7863
|
}
|
|
7820
7864
|
function mapSavedMessageAttachments(msg, messageObj, ctx) {
|
|
7821
7865
|
const loggedUserId = String(ctx.loggedUserDetails?._id || "");
|
|
@@ -7877,11 +7921,19 @@ function resolveSavedMessageContent(messageObj, msg) {
|
|
|
7877
7921
|
}
|
|
7878
7922
|
return { content: filename, messageType: "file", previewUrl: void 0 };
|
|
7879
7923
|
}
|
|
7880
|
-
if (messageType === "image")
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
if (messageType === "
|
|
7884
|
-
|
|
7924
|
+
if (messageType === "image") {
|
|
7925
|
+
return { content: getAttachmentTypePreviewLabel("image"), messageType, previewUrl: void 0 };
|
|
7926
|
+
}
|
|
7927
|
+
if (messageType === "video") {
|
|
7928
|
+
return { content: getAttachmentTypePreviewLabel("video"), messageType, previewUrl: void 0 };
|
|
7929
|
+
}
|
|
7930
|
+
if (messageType === "audio") {
|
|
7931
|
+
return { content: getAttachmentTypePreviewLabel("audio"), messageType, previewUrl: void 0 };
|
|
7932
|
+
}
|
|
7933
|
+
if (messageType === "file") {
|
|
7934
|
+
return { content: getAttachmentTypePreviewLabel("file"), messageType, previewUrl: void 0 };
|
|
7935
|
+
}
|
|
7936
|
+
return { content: getAttachmentTypePreviewLabel("file"), messageType, previewUrl: void 0 };
|
|
7885
7937
|
}
|
|
7886
7938
|
function getMessageId(msg) {
|
|
7887
7939
|
if (msg?.messageId && typeof msg.messageId === "object") {
|
|
@@ -7915,7 +7967,7 @@ function readSenderFromRecord(record) {
|
|
|
7915
7967
|
}
|
|
7916
7968
|
function resolveSenderName(msg, ctx) {
|
|
7917
7969
|
const messageObj = getMessageObject(msg);
|
|
7918
|
-
const
|
|
7970
|
+
const messageId2 = getMessageId(msg);
|
|
7919
7971
|
const loggedId = String(ctx.loggedUserDetails?._id || "");
|
|
7920
7972
|
const tryRecord = (record) => {
|
|
7921
7973
|
const parsed = readSenderFromRecord(record);
|
|
@@ -7932,9 +7984,9 @@ function resolveSenderName(msg, ctx) {
|
|
|
7932
7984
|
const hit = tryRecord(record);
|
|
7933
7985
|
if (hit) return hit;
|
|
7934
7986
|
}
|
|
7935
|
-
if (
|
|
7987
|
+
if (messageId2 && ctx.conversationMessages?.length) {
|
|
7936
7988
|
const found = ctx.conversationMessages.find(
|
|
7937
|
-
(m) => String(m._id || m.id) === String(
|
|
7989
|
+
(m) => String(m._id || m.id) === String(messageId2)
|
|
7938
7990
|
);
|
|
7939
7991
|
if (found) {
|
|
7940
7992
|
const hit = tryRecord(found);
|
|
@@ -7985,7 +8037,7 @@ function parseSavedMessage(msg, ctx = {}) {
|
|
|
7985
8037
|
const mode = ctx.mode || "pinned";
|
|
7986
8038
|
const prefs = ctx.dateTimePrefs ?? {};
|
|
7987
8039
|
if (msg?.isAttachment) {
|
|
7988
|
-
const
|
|
8040
|
+
const messageId3 = String(msg.messageId || "");
|
|
7989
8041
|
const attachmentId2 = String(msg.attachmentId || msg._id || "");
|
|
7990
8042
|
const attachments2 = mapSavedMessageAttachments(msg, null, ctx);
|
|
7991
8043
|
const { content: content2, previewUrl: previewUrl2, messageType: messageType2 } = resolveSavedMessageContent(null, msg);
|
|
@@ -7993,8 +8045,8 @@ function parseSavedMessage(msg, ctx = {}) {
|
|
|
7993
8045
|
const actionAt2 = msg?.createdAt || msg?.updatedAt || "";
|
|
7994
8046
|
const bodyText2 = String(msg.attachment?.caption || "").trim() || void 0;
|
|
7995
8047
|
return {
|
|
7996
|
-
id: attachmentId2 ||
|
|
7997
|
-
messageId:
|
|
8048
|
+
id: attachmentId2 || messageId3,
|
|
8049
|
+
messageId: messageId3,
|
|
7998
8050
|
attachmentId: attachmentId2 || void 0,
|
|
7999
8051
|
content: content2,
|
|
8000
8052
|
bodyText: bodyText2,
|
|
@@ -8013,7 +8065,7 @@ function parseSavedMessage(msg, ctx = {}) {
|
|
|
8013
8065
|
}
|
|
8014
8066
|
const messageObj = getMessageObject(msg);
|
|
8015
8067
|
const id = getMessageId(msg);
|
|
8016
|
-
const
|
|
8068
|
+
const messageId2 = id;
|
|
8017
8069
|
const attachmentId = msg?.attachmentId ? String(msg.attachmentId) : void 0;
|
|
8018
8070
|
const attachments = mapSavedMessageAttachments(msg, messageObj, ctx);
|
|
8019
8071
|
const rawContent = messageObj?.content ?? msg?.content ?? msg?.messageId?.content ?? "";
|
|
@@ -8035,8 +8087,8 @@ function parseSavedMessage(msg, ctx = {}) {
|
|
|
8035
8087
|
metaLabel = "Starred by you";
|
|
8036
8088
|
}
|
|
8037
8089
|
return {
|
|
8038
|
-
id: attachmentId ? `${
|
|
8039
|
-
messageId,
|
|
8090
|
+
id: attachmentId ? `${messageId2}:${attachmentId}` : id,
|
|
8091
|
+
messageId: messageId2,
|
|
8040
8092
|
attachmentId,
|
|
8041
8093
|
content: displayContent,
|
|
8042
8094
|
bodyText,
|
|
@@ -8066,6 +8118,22 @@ function groupSavedMessages(items) {
|
|
|
8066
8118
|
}));
|
|
8067
8119
|
}
|
|
8068
8120
|
|
|
8121
|
+
// src/chat/lib/chat-attachment-display.ts
|
|
8122
|
+
init_chat_constants();
|
|
8123
|
+
function cleanAttachmentDisplayName(filename, fallback = "Attachment") {
|
|
8124
|
+
const trimmed = filename.trim();
|
|
8125
|
+
if (!trimmed) return fallback;
|
|
8126
|
+
let name = trimmed;
|
|
8127
|
+
const prefixPattern = new RegExp(`^\\d{${ATTACHMENT_FILENAME_TIMESTAMP_LENGTH}}_`);
|
|
8128
|
+
while (prefixPattern.test(name)) {
|
|
8129
|
+
name = name.slice(ATTACHMENT_FILENAME_TIMESTAMP_LENGTH + 1);
|
|
8130
|
+
}
|
|
8131
|
+
if (name.length > ATTACHMENT_FILENAME_TIMESTAMP_LENGTH && /^\d+$/.test(name.slice(0, ATTACHMENT_FILENAME_TIMESTAMP_LENGTH)) && name[ATTACHMENT_FILENAME_TIMESTAMP_LENGTH] !== "_") {
|
|
8132
|
+
name = name.slice(ATTACHMENT_FILENAME_TIMESTAMP_LENGTH);
|
|
8133
|
+
}
|
|
8134
|
+
return name.trim() || trimmed;
|
|
8135
|
+
}
|
|
8136
|
+
|
|
8069
8137
|
// src/chat/header/saved-message/saved-message-utils.ts
|
|
8070
8138
|
var AVATAR_PALETTES = [
|
|
8071
8139
|
"bg-violet-500/15 text-violet-600 dark:text-violet-300",
|
|
@@ -8487,6 +8555,18 @@ var MessageStatus = ({ status, isPending, className }) => {
|
|
|
8487
8555
|
) });
|
|
8488
8556
|
};
|
|
8489
8557
|
var MessageStatus_default = MessageStatus;
|
|
8558
|
+
function GroupSenderName({ name, className }) {
|
|
8559
|
+
return /* @__PURE__ */ jsx(
|
|
8560
|
+
"span",
|
|
8561
|
+
{
|
|
8562
|
+
className: cn(
|
|
8563
|
+
"block max-w-full truncate text-[13px] font-semibold leading-[1.15] tracking-tight text-(--chat-incoming-text)",
|
|
8564
|
+
className
|
|
8565
|
+
),
|
|
8566
|
+
children: name
|
|
8567
|
+
}
|
|
8568
|
+
);
|
|
8569
|
+
}
|
|
8490
8570
|
function ForwardDoubleIcon({ className }) {
|
|
8491
8571
|
return /* @__PURE__ */ jsxs(
|
|
8492
8572
|
"svg",
|
|
@@ -8524,22 +8604,10 @@ function MessageForwardedLabel({ isSender, className, overlay }) {
|
|
|
8524
8604
|
}
|
|
8525
8605
|
);
|
|
8526
8606
|
}
|
|
8527
|
-
function GroupSenderName({ name, className }) {
|
|
8528
|
-
return /* @__PURE__ */ jsx(
|
|
8529
|
-
"span",
|
|
8530
|
-
{
|
|
8531
|
-
className: cn(
|
|
8532
|
-
"block max-w-full truncate text-[13px] font-semibold leading-[1.15] tracking-tight text-(--chat-incoming-text)",
|
|
8533
|
-
className
|
|
8534
|
-
),
|
|
8535
|
-
children: name
|
|
8536
|
-
}
|
|
8537
|
-
);
|
|
8538
|
-
}
|
|
8539
8607
|
|
|
8540
8608
|
// src/chat/lib/chat-message-bubble.ts
|
|
8541
|
-
function getBubbleCornerClasses() {
|
|
8542
|
-
return "rounded-tl-[18px] rounded-tr-[18px] rounded-br-[18px] rounded-bl-none";
|
|
8609
|
+
function getBubbleCornerClasses(isSender) {
|
|
8610
|
+
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";
|
|
8543
8611
|
}
|
|
8544
8612
|
function getChatBubbleClasses({
|
|
8545
8613
|
isSender = false,
|
|
@@ -8550,7 +8618,7 @@ function getChatBubbleClasses({
|
|
|
8550
8618
|
const isNeutral = resolvedSurface === "neutral";
|
|
8551
8619
|
return cn(
|
|
8552
8620
|
"relative",
|
|
8553
|
-
getBubbleCornerClasses(),
|
|
8621
|
+
getBubbleCornerClasses(isSender),
|
|
8554
8622
|
resolvedSurface === "sent" && "chat-bubble-sent bg-(--chat-theme) text-white",
|
|
8555
8623
|
resolvedSurface === "received" && "chat-bubble-received border border-(--chat-border)/60 bg-(--chat-incoming-bubble) text-(--chat-incoming-text)",
|
|
8556
8624
|
isNeutral && "chat-bubble-received border border-(--chat-border)/60 bg-(--chat-incoming-bubble) text-(--chat-incoming-text)",
|
|
@@ -8848,7 +8916,7 @@ function MessageAttachmentsCaptionBar({
|
|
|
8848
8916
|
onCancelEdit
|
|
8849
8917
|
}) {
|
|
8850
8918
|
if (isStandaloneMetaOnly) {
|
|
8851
|
-
return /* @__PURE__ */ jsx("div", { className: "flex justify-end pt-0.5", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
8919
|
+
return /* @__PURE__ */ jsx("div", { className: "flex justify-end pt-1.5 pb-0.5", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
8852
8920
|
/* @__PURE__ */ jsx(
|
|
8853
8921
|
MessageCornerBadges,
|
|
8854
8922
|
{
|
|
@@ -10059,6 +10127,8 @@ function FileAttachmentRow({
|
|
|
10059
10127
|
}
|
|
10060
10128
|
window.open(fileUrl, "_blank", "noopener,noreferrer");
|
|
10061
10129
|
};
|
|
10130
|
+
const onThemeBubble = inBubble && isSender;
|
|
10131
|
+
const onIncomingBubble = inBubble && !isSender;
|
|
10062
10132
|
return /* @__PURE__ */ jsxs(
|
|
10063
10133
|
"div",
|
|
10064
10134
|
{
|
|
@@ -10066,8 +10136,11 @@ function FileAttachmentRow({
|
|
|
10066
10136
|
"group w-full transition-opacity",
|
|
10067
10137
|
!stacked && "flex min-w-[220px] items-center gap-2",
|
|
10068
10138
|
stacked && "py-1.5",
|
|
10069
|
-
stacked && showDivider && (
|
|
10070
|
-
!stacked &&
|
|
10139
|
+
stacked && showDivider && (onThemeBubble ? "border-t border-white/15" : "border-t border-(--chat-border)/35"),
|
|
10140
|
+
!stacked && "rounded-xl border p-2.5",
|
|
10141
|
+
!stacked && onThemeBubble && "border-white/20 bg-white/12 text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.08)] backdrop-blur-[2px]",
|
|
10142
|
+
!stacked && onIncomingBubble && "border-(--chat-border)/70 bg-(--chat-elevated) text-(--chat-text) shadow-sm [.dark_&]:bg-(--chat-surface)",
|
|
10143
|
+
!stacked && !inBubble && "border-(--chat-border) bg-(--chat-surface) shadow-sm",
|
|
10071
10144
|
!fileUrl && "pointer-events-none opacity-60",
|
|
10072
10145
|
isCaptionActive && "opacity-90"
|
|
10073
10146
|
),
|
|
@@ -10079,36 +10152,31 @@ function FileAttachmentRow({
|
|
|
10079
10152
|
type: "button",
|
|
10080
10153
|
onClick: handleFileOpen,
|
|
10081
10154
|
disabled: !fileUrl || selectionMode,
|
|
10082
|
-
className: "flex min-w-0 flex-1 items-center gap-2 text-left disabled:cursor-default",
|
|
10155
|
+
className: "flex min-w-0 flex-1 items-center gap-2.5 text-left disabled:cursor-default",
|
|
10083
10156
|
children: [
|
|
10084
10157
|
/* @__PURE__ */ jsx("div", { className: cn(
|
|
10085
|
-
"flex shrink-0 items-center justify-center rounded-lg text-white",
|
|
10086
|
-
stacked ? "size-9" : "size-10 rounded-xl shadow-sm",
|
|
10158
|
+
"flex size-10 shrink-0 items-center justify-center rounded-lg text-white shadow-sm",
|
|
10087
10159
|
getAttachmentIconBoxClass(rawName)
|
|
10088
|
-
), children: getAttachmentIcon(rawName, "file", "text-white",
|
|
10160
|
+
), children: getAttachmentIcon(rawName, "file", "text-white", 18) }),
|
|
10089
10161
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
10090
10162
|
/* @__PURE__ */ jsx("span", { className: cn(
|
|
10091
|
-
"block truncate text-
|
|
10092
|
-
|
|
10163
|
+
"block truncate text-[12px] font-semibold leading-tight",
|
|
10164
|
+
onThemeBubble ? "text-white" : "text-(--chat-text)"
|
|
10093
10165
|
), children: displayName }),
|
|
10094
10166
|
/* @__PURE__ */ jsx("span", { className: cn(
|
|
10095
|
-
"mt-0.5 block truncate text-[10px] leading-tight uppercase",
|
|
10096
|
-
|
|
10167
|
+
"mt-0.5 block truncate text-[10px] font-medium leading-tight uppercase tracking-wide",
|
|
10168
|
+
onThemeBubble ? "text-white/70" : "text-(--chat-muted)"
|
|
10097
10169
|
), children: subtitle })
|
|
10098
10170
|
] }),
|
|
10099
10171
|
/* @__PURE__ */ jsx(
|
|
10100
10172
|
"span",
|
|
10101
10173
|
{
|
|
10102
10174
|
className: cn(
|
|
10103
|
-
"flex shrink-0 items-center justify-center transition-colors",
|
|
10104
|
-
|
|
10105
|
-
"size-7 rounded-lg border",
|
|
10106
|
-
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)"
|
|
10107
|
-
),
|
|
10108
|
-
stacked && inBubble && isSender && "text-white/70 group-hover:text-white"
|
|
10175
|
+
"flex size-8 shrink-0 items-center justify-center rounded-full transition-colors",
|
|
10176
|
+
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)"
|
|
10109
10177
|
),
|
|
10110
10178
|
"aria-hidden": true,
|
|
10111
|
-
children: /* @__PURE__ */ jsx(Eye, { size:
|
|
10179
|
+
children: /* @__PURE__ */ jsx(Eye, { size: 14 })
|
|
10112
10180
|
}
|
|
10113
10181
|
)
|
|
10114
10182
|
]
|
|
@@ -10119,13 +10187,13 @@ function FileAttachmentRow({
|
|
|
10119
10187
|
{
|
|
10120
10188
|
onClick: onEditCaption,
|
|
10121
10189
|
label: `${attachmentCaption ? "Edit" : "Add"} caption for ${displayName}`,
|
|
10122
|
-
className:
|
|
10190
|
+
className: onThemeBubble ? "text-white/60 hover:text-white" : void 0
|
|
10123
10191
|
}
|
|
10124
10192
|
)
|
|
10125
10193
|
] }),
|
|
10126
10194
|
stacked && attachmentCaption ? /* @__PURE__ */ jsx("p", { className: cn(
|
|
10127
|
-
"mt-1 whitespace-pre-wrap break-words pl-
|
|
10128
|
-
|
|
10195
|
+
"mt-1 whitespace-pre-wrap break-words pl-12 pr-8 text-[11px] leading-snug",
|
|
10196
|
+
onThemeBubble ? "text-white/85" : "text-(--chat-text-secondary)"
|
|
10129
10197
|
), children: attachmentCaption }) : null
|
|
10130
10198
|
]
|
|
10131
10199
|
}
|
|
@@ -10244,17 +10312,30 @@ function MessageAttachmentsNonImageSection({
|
|
|
10244
10312
|
att.id
|
|
10245
10313
|
);
|
|
10246
10314
|
};
|
|
10247
|
-
return /* @__PURE__ */ jsx(
|
|
10315
|
+
return /* @__PURE__ */ jsx("div", { className: "flex w-full flex-col gap-1.5", children: nonImageGroups.map((group) => {
|
|
10248
10316
|
if (group.kind === "file-run") {
|
|
10249
10317
|
if (group.items.length === 1) {
|
|
10250
10318
|
return renderFileAttachmentFrame(group.items[0]);
|
|
10251
10319
|
}
|
|
10252
|
-
return /* @__PURE__ */ jsx(
|
|
10253
|
-
|
|
10254
|
-
|
|
10255
|
-
|
|
10256
|
-
|
|
10257
|
-
|
|
10320
|
+
return /* @__PURE__ */ jsx(
|
|
10321
|
+
"div",
|
|
10322
|
+
{
|
|
10323
|
+
className: cn(
|
|
10324
|
+
"w-full min-w-[220px]",
|
|
10325
|
+
isBubbleLayout && "rounded-xl border p-2",
|
|
10326
|
+
isBubbleLayout && isSender && "border-white/20 bg-white/12 shadow-[inset_0_1px_0_rgba(255,255,255,0.08)] backdrop-blur-[2px]",
|
|
10327
|
+
isBubbleLayout && !isSender && "border-(--chat-border)/70 bg-(--chat-elevated) shadow-sm [.dark_&]:bg-(--chat-surface)",
|
|
10328
|
+
!isBubbleLayout && "rounded-xl border border-(--chat-border) bg-(--chat-surface) p-2 shadow-sm"
|
|
10329
|
+
),
|
|
10330
|
+
children: group.items.map(
|
|
10331
|
+
(att2, index) => renderFileAttachmentFrame(att2, {
|
|
10332
|
+
stacked: true,
|
|
10333
|
+
showDivider: index > 0
|
|
10334
|
+
})
|
|
10335
|
+
)
|
|
10336
|
+
},
|
|
10337
|
+
`file-run-${group.items.map((item) => item.id).join("-")}`
|
|
10338
|
+
);
|
|
10258
10339
|
}
|
|
10259
10340
|
const att = group.item;
|
|
10260
10341
|
const type = resolveAttachmentType(att);
|
|
@@ -10327,7 +10408,8 @@ function MessageAttachmentsView({
|
|
|
10327
10408
|
isGroupedWithPrev = false,
|
|
10328
10409
|
isGroupedWithNext = false,
|
|
10329
10410
|
showSenderLabel = false,
|
|
10330
|
-
senderName
|
|
10411
|
+
senderName,
|
|
10412
|
+
senderId
|
|
10331
10413
|
}) {
|
|
10332
10414
|
const [documentPreview, setDocumentPreview] = useState(null);
|
|
10333
10415
|
const visibleAttachments = getVisibleAttachments(attachments);
|
|
@@ -10368,7 +10450,10 @@ function MessageAttachmentsView({
|
|
|
10368
10450
|
isSender,
|
|
10369
10451
|
surface: bubbleSurface,
|
|
10370
10452
|
className: cn(
|
|
10371
|
-
isImageOnlyBubble ? "overflow-hidden p-0" : isForwarded || canShowSenderName ? "px-2 py-
|
|
10453
|
+
isImageOnlyBubble ? "overflow-hidden p-0" : isForwarded || canShowSenderName ? "px-2 py-1" : cn(
|
|
10454
|
+
"px-2.5",
|
|
10455
|
+
nonImages.length > 1 || images.length > 0 && nonImages.length > 0 ? "py-1.5" : "py-1"
|
|
10456
|
+
)
|
|
10372
10457
|
)
|
|
10373
10458
|
})
|
|
10374
10459
|
),
|
|
@@ -10381,7 +10466,13 @@ function MessageAttachmentsView({
|
|
|
10381
10466
|
isImageOnlyBubble ? "px-2.5 pt-1.5 pb-1" : "px-0.5 pb-0.5"
|
|
10382
10467
|
),
|
|
10383
10468
|
children: [
|
|
10384
|
-
canShowSenderName ? /* @__PURE__ */ jsx(
|
|
10469
|
+
canShowSenderName ? /* @__PURE__ */ jsx(
|
|
10470
|
+
GroupSenderName,
|
|
10471
|
+
{
|
|
10472
|
+
name: senderName,
|
|
10473
|
+
colorSeed: senderId || senderName
|
|
10474
|
+
}
|
|
10475
|
+
) : null,
|
|
10385
10476
|
showForwardedInHeader ? /* @__PURE__ */ jsx(
|
|
10386
10477
|
MessageForwardedLabel,
|
|
10387
10478
|
{
|
|
@@ -10395,7 +10486,7 @@ function MessageAttachmentsView({
|
|
|
10395
10486
|
isBubbleLayout && replySnippet ? /* @__PURE__ */ jsx("div", { className: "px-2 pb-1", children: replySnippet }) : null,
|
|
10396
10487
|
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
10397
10488
|
"flex w-full flex-col",
|
|
10398
|
-
!isImageOnlyBubble && "gap-0",
|
|
10489
|
+
!isImageOnlyBubble && (images.length > 0 && nonImages.length > 0 ? "gap-1.5" : "gap-0"),
|
|
10399
10490
|
isImageOnlyBubble && "relative overflow-hidden"
|
|
10400
10491
|
), children: [
|
|
10401
10492
|
/* @__PURE__ */ jsx(
|
|
@@ -10925,7 +11016,7 @@ function collectConversationAttachments(messages) {
|
|
|
10925
11016
|
const items = [];
|
|
10926
11017
|
for (const message of messages) {
|
|
10927
11018
|
if (message?.isDeletedForEveryone) continue;
|
|
10928
|
-
const
|
|
11019
|
+
const messageId2 = String(message._id || message.id || "");
|
|
10929
11020
|
const createdAt = message.createdAt || message.timestamp;
|
|
10930
11021
|
const messageType = message.type || "text";
|
|
10931
11022
|
for (const attachment of message.attachments || []) {
|
|
@@ -10943,13 +11034,35 @@ function collectConversationAttachments(messages) {
|
|
|
10943
11034
|
url,
|
|
10944
11035
|
name,
|
|
10945
11036
|
type: resolveFileCategory(name, fileType, resolvedType),
|
|
10946
|
-
messageId,
|
|
11037
|
+
messageId: messageId2,
|
|
10947
11038
|
createdAt,
|
|
10948
11039
|
size: typeof attachment.size === "number" ? attachment.size : void 0,
|
|
10949
11040
|
duration: typeof attachment.duration === "number" ? attachment.duration : void 0,
|
|
10950
11041
|
fileType
|
|
10951
11042
|
});
|
|
10952
11043
|
}
|
|
11044
|
+
if ((message.attachments || []).length === 0) {
|
|
11045
|
+
const rootUrl = message.url || message.fileUrl || message.attachmentUrl || message.public_link || message.publicLink || "";
|
|
11046
|
+
if (!rootUrl) continue;
|
|
11047
|
+
const name = message.filename || message.fileName || message.name || "Attachment";
|
|
11048
|
+
const fileType = message.fileType || message.mimeType || "";
|
|
11049
|
+
const dedupeKey = `${rootUrl}|${name}`;
|
|
11050
|
+
if (seen.has(dedupeKey)) continue;
|
|
11051
|
+
seen.add(dedupeKey);
|
|
11052
|
+
const baseType = inferAttachmentType(fileType, name);
|
|
11053
|
+
const resolvedType = messageType === "image" && baseType === "file" ? "image" : baseType;
|
|
11054
|
+
items.push({
|
|
11055
|
+
id: String(message.attachmentId || message.fileId || dedupeKey),
|
|
11056
|
+
url: rootUrl,
|
|
11057
|
+
name,
|
|
11058
|
+
type: resolveFileCategory(name, fileType, resolvedType),
|
|
11059
|
+
messageId: messageId2,
|
|
11060
|
+
createdAt,
|
|
11061
|
+
size: typeof message.size === "number" ? message.size : void 0,
|
|
11062
|
+
duration: typeof message.duration === "number" ? message.duration : void 0,
|
|
11063
|
+
fileType
|
|
11064
|
+
});
|
|
11065
|
+
}
|
|
10953
11066
|
}
|
|
10954
11067
|
return items.sort(
|
|
10955
11068
|
(a, b) => new Date(b.createdAt || 0).getTime() - new Date(a.createdAt || 0).getTime()
|
|
@@ -11160,9 +11273,13 @@ function AttachmentSection({
|
|
|
11160
11273
|
}
|
|
11161
11274
|
var AttachmentsDrawer = ({ isOpen, onOpenChange, conversationId }) => {
|
|
11162
11275
|
const messagesByConversation = useStore((s) => s.messagesByConversation);
|
|
11276
|
+
const messagesMetadata = useStore((s) => s.messagesMetadata);
|
|
11277
|
+
const fetchMessages2 = useStore((s) => s.fetchMessages);
|
|
11163
11278
|
const [sectionVisibleCount, setSectionVisibleCount] = useState({});
|
|
11164
11279
|
const [documentPreview, setDocumentPreview] = useState(null);
|
|
11165
11280
|
const [imageLightboxIndex, setImageLightboxIndex] = useState(null);
|
|
11281
|
+
const hasLoadedMessages = conversationId ? Boolean(messagesMetadata[conversationId]?.isFirstPage) : false;
|
|
11282
|
+
const isLoading = isOpen && !!conversationId && !hasLoadedMessages;
|
|
11166
11283
|
useEffect(() => {
|
|
11167
11284
|
if (!isOpen) {
|
|
11168
11285
|
setSectionVisibleCount({});
|
|
@@ -11173,6 +11290,10 @@ var AttachmentsDrawer = ({ isOpen, onOpenChange, conversationId }) => {
|
|
|
11173
11290
|
useEffect(() => {
|
|
11174
11291
|
setSectionVisibleCount({});
|
|
11175
11292
|
}, [conversationId]);
|
|
11293
|
+
useEffect(() => {
|
|
11294
|
+
if (!isOpen || !conversationId || hasLoadedMessages) return;
|
|
11295
|
+
fetchMessages2(conversationId);
|
|
11296
|
+
}, [isOpen, conversationId, hasLoadedMessages, fetchMessages2]);
|
|
11176
11297
|
const attachments = useMemo(() => {
|
|
11177
11298
|
if (!conversationId) return [];
|
|
11178
11299
|
const messages = messagesByConversation[conversationId] || [];
|
|
@@ -11224,7 +11345,11 @@ var AttachmentsDrawer = ({ isOpen, onOpenChange, conversationId }) => {
|
|
|
11224
11345
|
] }),
|
|
11225
11346
|
/* @__PURE__ */ jsx("p", { className: "mt-1 text-[11px] text-(--chat-muted)", children: "Shared media and files" })
|
|
11226
11347
|
] }) }),
|
|
11227
|
-
/* @__PURE__ */ jsx("div", { className: "chat-message-scroll flex-1 overflow-y-auto bg-(--chat-main-bg) px-2.5 py-2", children:
|
|
11348
|
+
/* @__PURE__ */ jsx("div", { className: "chat-message-scroll flex-1 overflow-y-auto bg-(--chat-main-bg) px-2.5 py-2", children: isLoading ? /* @__PURE__ */ jsxs("div", { className: "flex min-h-[220px] flex-col items-center justify-center px-4 text-center", children: [
|
|
11349
|
+
/* @__PURE__ */ jsx(Loader2, { className: "mb-3 size-8 animate-spin text-(--chat-theme)" }),
|
|
11350
|
+
/* @__PURE__ */ jsx("p", { className: "text-[13px] font-medium text-(--chat-text)", children: "Loading attachments..." }),
|
|
11351
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-[11px] text-(--chat-muted)", children: "Fetching shared files for this chat" })
|
|
11352
|
+
] }) : attachments.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "chat-saved-empty flex min-h-[220px] flex-col items-center justify-center px-4 text-center", children: [
|
|
11228
11353
|
/* @__PURE__ */ jsx("div", { className: "mb-3", children: /* @__PURE__ */ jsx("div", { className: "chat-saved-empty-icon-wrap", children: /* @__PURE__ */ jsx(Paperclip, { size: 22, className: cn("chat-saved-empty-icon !text-(--chat-theme)") }) }) }),
|
|
11229
11354
|
/* @__PURE__ */ jsx("p", { className: "text-[14px] font-semibold text-(--chat-text)", children: "No attachments" }),
|
|
11230
11355
|
/* @__PURE__ */ jsx("p", { className: "mt-1.5 max-w-[240px] text-[12px] leading-relaxed text-(--chat-muted)", children: "Shared files will show up here." })
|
|
@@ -11607,7 +11732,7 @@ var ChannelDetailsDrawer = (props) => {
|
|
|
11607
11732
|
{
|
|
11608
11733
|
type: "button",
|
|
11609
11734
|
onClick: () => fileInputRef.current?.click(),
|
|
11610
|
-
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-
|
|
11735
|
+
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)",
|
|
11611
11736
|
title: "Change group avatar",
|
|
11612
11737
|
children: /* @__PURE__ */ jsx(Camera, { size: 12 })
|
|
11613
11738
|
}
|
|
@@ -11646,7 +11771,7 @@ var ChannelDetailsDrawer = (props) => {
|
|
|
11646
11771
|
{
|
|
11647
11772
|
variant: "outline",
|
|
11648
11773
|
size: "sm",
|
|
11649
|
-
className: "h-8 flex-1 text-[12px]",
|
|
11774
|
+
className: "h-8 flex-1 border-(--chat-border) bg-(--chat-surface) text-[12px] text-(--chat-text) hover:bg-(--chat-hover)",
|
|
11650
11775
|
onClick: () => setIsEditing(false),
|
|
11651
11776
|
children: [
|
|
11652
11777
|
/* @__PURE__ */ jsx(X, { className: "mr-1 size-3" }),
|
|
@@ -11658,7 +11783,7 @@ var ChannelDetailsDrawer = (props) => {
|
|
|
11658
11783
|
Button,
|
|
11659
11784
|
{
|
|
11660
11785
|
size: "sm",
|
|
11661
|
-
className: "h-8 flex-1 text-[12px]",
|
|
11786
|
+
className: "h-8 flex-1 border border-(--chat-theme) bg-(--chat-theme) text-[12px] text-white hover:opacity-90 disabled:opacity-50",
|
|
11662
11787
|
onClick: handleSave,
|
|
11663
11788
|
disabled: isSaving || imageUploadStatus === "uploading",
|
|
11664
11789
|
children: isSaving ? /* @__PURE__ */ jsx(Loader2, { className: "size-3 animate-spin" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -11676,7 +11801,7 @@ var ChannelDetailsDrawer = (props) => {
|
|
|
11676
11801
|
{
|
|
11677
11802
|
variant: "ghost",
|
|
11678
11803
|
size: "sm",
|
|
11679
|
-
className: "mt-2 h-7 gap-1 px-2 text-[11px] text-(--chat-
|
|
11804
|
+
className: "mt-2 h-7 gap-1 px-2 text-[11px] text-(--chat-theme) hover:bg-(--chat-theme-10) hover:text-(--chat-theme)",
|
|
11680
11805
|
onClick: () => setIsEditing(true),
|
|
11681
11806
|
children: [
|
|
11682
11807
|
/* @__PURE__ */ jsx(Pencil, { className: "size-3" }),
|
|
@@ -12534,8 +12659,8 @@ function useChannelHeader({
|
|
|
12534
12659
|
}
|
|
12535
12660
|
}
|
|
12536
12661
|
};
|
|
12537
|
-
const handleSelectSearchResult = async (
|
|
12538
|
-
await fetchSearchMessageContext(
|
|
12662
|
+
const handleSelectSearchResult = async (messageId2) => {
|
|
12663
|
+
await fetchSearchMessageContext(messageId2);
|
|
12539
12664
|
handleCloseSearch();
|
|
12540
12665
|
};
|
|
12541
12666
|
const handleSearchOpenChange = (open) => {
|
|
@@ -12571,6 +12696,14 @@ function useChannelHeader({
|
|
|
12571
12696
|
fetchStarredMessages2(conversationId);
|
|
12572
12697
|
}
|
|
12573
12698
|
}, [state.isFavoriteOpen, conversationId, fetchStarredMessages2]);
|
|
12699
|
+
useEffect(() => {
|
|
12700
|
+
if (state.isAttachmentsOpen && conversationId) {
|
|
12701
|
+
const meta = useStore.getState().messagesMetadata[conversationId];
|
|
12702
|
+
if (!meta?.isFirstPage) {
|
|
12703
|
+
fetchMessagesStore(conversationId);
|
|
12704
|
+
}
|
|
12705
|
+
}
|
|
12706
|
+
}, [state.isAttachmentsOpen, conversationId, fetchMessagesStore]);
|
|
12574
12707
|
const pinnedCount = liveCounts?.pinnedCount ?? activeChannel?.pinnedCount ?? 0;
|
|
12575
12708
|
const starredCount = liveCounts?.starredCount ?? activeChannel?.starredCount ?? 0;
|
|
12576
12709
|
const handleClearChat = () => {
|
|
@@ -12616,14 +12749,14 @@ function useChannelHeader({
|
|
|
12616
12749
|
updateState({ isBlockAlertOpen: false });
|
|
12617
12750
|
}
|
|
12618
12751
|
};
|
|
12619
|
-
const handleUnpin = (
|
|
12752
|
+
const handleUnpin = (messageId2, attachmentId) => {
|
|
12620
12753
|
if (!loggedUserDetails?._id || !conversationId || !activeChannel) return;
|
|
12621
|
-
const loadingKey = attachmentId ? `${
|
|
12754
|
+
const loadingKey = attachmentId ? `${messageId2}:${attachmentId}` : messageId2;
|
|
12622
12755
|
updateState({ loadingIds: new Set(state.loadingIds).add(loadingKey) });
|
|
12623
12756
|
const basePayload = {
|
|
12624
12757
|
conversationId,
|
|
12625
12758
|
sender: loggedUserDetails._id,
|
|
12626
|
-
messageId,
|
|
12759
|
+
messageId: messageId2,
|
|
12627
12760
|
receiver: activeChannel.id,
|
|
12628
12761
|
...attachmentId ? { attachmentId } : {}
|
|
12629
12762
|
};
|
|
@@ -12643,12 +12776,12 @@ function useChannelHeader({
|
|
|
12643
12776
|
if (!dateStr) return "";
|
|
12644
12777
|
return formatLongDate(dateStr);
|
|
12645
12778
|
};
|
|
12646
|
-
const handleUnstar = (
|
|
12779
|
+
const handleUnstar = (messageId2, attachmentId) => {
|
|
12647
12780
|
if (!loggedUserDetails?._id || !conversationId || !activeChannel) return;
|
|
12648
|
-
const loadingKey = attachmentId ? `${
|
|
12781
|
+
const loadingKey = attachmentId ? `${messageId2}:${attachmentId}` : messageId2;
|
|
12649
12782
|
updateState({ loadingIds: new Set(state.loadingIds).add(loadingKey) });
|
|
12650
12783
|
const basePayload = {
|
|
12651
|
-
messageId,
|
|
12784
|
+
messageId: messageId2,
|
|
12652
12785
|
sender: loggedUserDetails._id,
|
|
12653
12786
|
conversationId,
|
|
12654
12787
|
receiver: activeChannel.id,
|
|
@@ -12918,7 +13051,7 @@ var MessageReactions = ({
|
|
|
12918
13051
|
{
|
|
12919
13052
|
onClick: () => onReactionClick(emoji),
|
|
12920
13053
|
className: cn(
|
|
12921
|
-
"flex items-center gap-
|
|
13054
|
+
"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",
|
|
12922
13055
|
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)"
|
|
12923
13056
|
),
|
|
12924
13057
|
children: [
|
|
@@ -12972,7 +13105,7 @@ var MessageToolbar = ({
|
|
|
12972
13105
|
"div",
|
|
12973
13106
|
{
|
|
12974
13107
|
className: cn(
|
|
12975
|
-
"absolute -top-8 z-
|
|
13108
|
+
"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",
|
|
12976
13109
|
"bg-(--chat-toolbar-bg) text-(--chat-text)",
|
|
12977
13110
|
isSender ? "right-0" : "left-0"
|
|
12978
13111
|
),
|
|
@@ -13248,8 +13381,8 @@ init_useStore();
|
|
|
13248
13381
|
|
|
13249
13382
|
// src/chat/lib/chat-selection.ts
|
|
13250
13383
|
init_attachment_helpers();
|
|
13251
|
-
function buildSelectionKey(
|
|
13252
|
-
return pinKey(
|
|
13384
|
+
function buildSelectionKey(messageId2, attachmentId) {
|
|
13385
|
+
return pinKey(messageId2, attachmentId || null);
|
|
13253
13386
|
}
|
|
13254
13387
|
function parseSelectionKey(key) {
|
|
13255
13388
|
const colonIndex = key.indexOf(":");
|
|
@@ -13264,8 +13397,8 @@ function parseSelectionKey(key) {
|
|
|
13264
13397
|
function messageUsesAttachmentSelection(message) {
|
|
13265
13398
|
return getVisibleAttachments(message.attachments).length > 1;
|
|
13266
13399
|
}
|
|
13267
|
-
function getSelectedAttachmentIdsForMessage(selectedKeys,
|
|
13268
|
-
const prefix = `${
|
|
13400
|
+
function getSelectedAttachmentIdsForMessage(selectedKeys, messageId2) {
|
|
13401
|
+
const prefix = `${messageId2}:`;
|
|
13269
13402
|
const ids = /* @__PURE__ */ new Set();
|
|
13270
13403
|
selectedKeys.forEach((key) => {
|
|
13271
13404
|
if (key.startsWith(prefix)) {
|
|
@@ -13274,14 +13407,14 @@ function getSelectedAttachmentIdsForMessage(selectedKeys, messageId) {
|
|
|
13274
13407
|
});
|
|
13275
13408
|
return ids;
|
|
13276
13409
|
}
|
|
13277
|
-
function isMessageWhollySelected(selectedKeys,
|
|
13278
|
-
return selectedKeys.has(
|
|
13410
|
+
function isMessageWhollySelected(selectedKeys, messageId2) {
|
|
13411
|
+
return selectedKeys.has(messageId2);
|
|
13279
13412
|
}
|
|
13280
13413
|
function resolveForwardItems(selectedKeys, messages) {
|
|
13281
13414
|
const items = [];
|
|
13282
13415
|
selectedKeys.forEach((key) => {
|
|
13283
|
-
const { messageId, attachmentId } = parseSelectionKey(key);
|
|
13284
|
-
const message = messages.find((entry) => String(entry._id || entry.id) ===
|
|
13416
|
+
const { messageId: messageId2, attachmentId } = parseSelectionKey(key);
|
|
13417
|
+
const message = messages.find((entry) => String(entry._id || entry.id) === messageId2);
|
|
13285
13418
|
if (!message) return;
|
|
13286
13419
|
items.push({ message, attachmentId });
|
|
13287
13420
|
});
|
|
@@ -13307,7 +13440,7 @@ function useMessageItemActions({
|
|
|
13307
13440
|
message,
|
|
13308
13441
|
createdAt,
|
|
13309
13442
|
attachments,
|
|
13310
|
-
messageId,
|
|
13443
|
+
messageId: messageId2,
|
|
13311
13444
|
receiver,
|
|
13312
13445
|
isDeletedForEveryone,
|
|
13313
13446
|
reactions,
|
|
@@ -13359,10 +13492,10 @@ function useMessageItemActions({
|
|
|
13359
13492
|
const allUsers = useStore((s) => s.allUsers);
|
|
13360
13493
|
const loggedUserDetails = useStore((s) => s.loggedUserDetails);
|
|
13361
13494
|
const pinnedMessagesByConversation = useStore((s) => s.pinnedMessagesByConversation);
|
|
13362
|
-
const mid = String(
|
|
13495
|
+
const mid = String(messageId2 || "");
|
|
13363
13496
|
const pendingActions = mid ? messagePendingActions[mid] || [] : [];
|
|
13364
13497
|
const isPending = Boolean(
|
|
13365
|
-
isSender && (String(
|
|
13498
|
+
isSender && (String(messageId2 || "").startsWith("temp-") || mid && (messagePendingActions[mid] || []).includes("send"))
|
|
13366
13499
|
);
|
|
13367
13500
|
const isEditPending = pendingActions.includes("edit");
|
|
13368
13501
|
const isDeletePending = pendingActions.includes("delete");
|
|
@@ -13400,13 +13533,13 @@ function useMessageItemActions({
|
|
|
13400
13533
|
};
|
|
13401
13534
|
const handleSaveAttachmentCaption = (caption, attachment) => {
|
|
13402
13535
|
const target = attachment ?? state.captionModalAttachment;
|
|
13403
|
-
if (!
|
|
13536
|
+
if (!messageId2 || !loggedUserDetails || !target) return;
|
|
13404
13537
|
const attachmentId = target.id;
|
|
13405
13538
|
if (isGroup) {
|
|
13406
13539
|
if (!conversationId) return;
|
|
13407
13540
|
emitGroupEdit({
|
|
13408
13541
|
content: caption,
|
|
13409
|
-
messageId,
|
|
13542
|
+
messageId: messageId2,
|
|
13410
13543
|
sender: loggedUserDetails._id,
|
|
13411
13544
|
conversationId,
|
|
13412
13545
|
attachmentId
|
|
@@ -13415,7 +13548,7 @@ function useMessageItemActions({
|
|
|
13415
13548
|
if (!receiver) return;
|
|
13416
13549
|
emitDmEdit({
|
|
13417
13550
|
content: caption,
|
|
13418
|
-
messageId,
|
|
13551
|
+
messageId: messageId2,
|
|
13419
13552
|
sender: loggedUserDetails._id,
|
|
13420
13553
|
receiver,
|
|
13421
13554
|
attachmentId
|
|
@@ -13432,12 +13565,12 @@ function useMessageItemActions({
|
|
|
13432
13565
|
onEnterSelectionMode?.();
|
|
13433
13566
|
};
|
|
13434
13567
|
const handleSaveEdit = () => {
|
|
13435
|
-
if (!
|
|
13568
|
+
if (!messageId2 || !loggedUserDetails) return;
|
|
13436
13569
|
if (isGroup) {
|
|
13437
13570
|
if (!conversationId) return;
|
|
13438
13571
|
emitGroupEdit({
|
|
13439
13572
|
content: state.editValue.trim(),
|
|
13440
|
-
messageId,
|
|
13573
|
+
messageId: messageId2,
|
|
13441
13574
|
sender: loggedUserDetails._id,
|
|
13442
13575
|
conversationId
|
|
13443
13576
|
});
|
|
@@ -13445,7 +13578,7 @@ function useMessageItemActions({
|
|
|
13445
13578
|
if (!receiver) return;
|
|
13446
13579
|
emitDmEdit({
|
|
13447
13580
|
content: state.editValue.trim(),
|
|
13448
|
-
messageId,
|
|
13581
|
+
messageId: messageId2,
|
|
13449
13582
|
sender: loggedUserDetails._id,
|
|
13450
13583
|
receiver
|
|
13451
13584
|
});
|
|
@@ -13456,7 +13589,7 @@ function useMessageItemActions({
|
|
|
13456
13589
|
updateState({ isEditing: false, editValue: message });
|
|
13457
13590
|
};
|
|
13458
13591
|
const handleDeleteMessage = (deleteType) => {
|
|
13459
|
-
if (!
|
|
13592
|
+
if (!messageId2 || !loggedUserDetails) return;
|
|
13460
13593
|
if (deleteType === "everyone" && !isSender) return;
|
|
13461
13594
|
if (deleteType === "everyone" && !isWithinEditWindow()) return;
|
|
13462
13595
|
const attachmentIds = hasAttachments ? deleteAttachmentIds : [];
|
|
@@ -13464,7 +13597,7 @@ function useMessageItemActions({
|
|
|
13464
13597
|
if (isGroup) {
|
|
13465
13598
|
if (!conversationId) return;
|
|
13466
13599
|
emitGroupDelete({
|
|
13467
|
-
messageId,
|
|
13600
|
+
messageId: messageId2,
|
|
13468
13601
|
sender: loggedUserDetails._id,
|
|
13469
13602
|
deleteType,
|
|
13470
13603
|
conversationId,
|
|
@@ -13473,7 +13606,7 @@ function useMessageItemActions({
|
|
|
13473
13606
|
} else {
|
|
13474
13607
|
if (!receiver) return;
|
|
13475
13608
|
emitDmDelete({
|
|
13476
|
-
messageId,
|
|
13609
|
+
messageId: messageId2,
|
|
13477
13610
|
sender: loggedUserDetails._id,
|
|
13478
13611
|
receiver,
|
|
13479
13612
|
deleteType,
|
|
@@ -13495,7 +13628,7 @@ function useMessageItemActions({
|
|
|
13495
13628
|
onForward?.();
|
|
13496
13629
|
};
|
|
13497
13630
|
const handleReactionClick = (emojiObject) => {
|
|
13498
|
-
if (!
|
|
13631
|
+
if (!messageId2 || !loggedUserDetails) return;
|
|
13499
13632
|
const reaction = typeof emojiObject === "string" ? emojiObject : emojiObject.emoji || emojiObject.native;
|
|
13500
13633
|
const hasReacted = reactions?.some(
|
|
13501
13634
|
(r) => r.reaction === reaction && String(r.addedBy?._id || r.addedBy || r.sender?._id || r.sender) === String(loggedUserDetails._id)
|
|
@@ -13504,7 +13637,7 @@ function useMessageItemActions({
|
|
|
13504
13637
|
if (isGroup) {
|
|
13505
13638
|
if (!conversationId) return;
|
|
13506
13639
|
emitGroupReactionRemove({
|
|
13507
|
-
messageId,
|
|
13640
|
+
messageId: messageId2,
|
|
13508
13641
|
sender: loggedUserDetails._id,
|
|
13509
13642
|
reaction,
|
|
13510
13643
|
conversationId
|
|
@@ -13512,7 +13645,7 @@ function useMessageItemActions({
|
|
|
13512
13645
|
} else {
|
|
13513
13646
|
if (!receiver) return;
|
|
13514
13647
|
emitDmReactionRemove({
|
|
13515
|
-
messageId,
|
|
13648
|
+
messageId: messageId2,
|
|
13516
13649
|
sender: loggedUserDetails._id,
|
|
13517
13650
|
receiver,
|
|
13518
13651
|
reaction,
|
|
@@ -13523,7 +13656,7 @@ function useMessageItemActions({
|
|
|
13523
13656
|
if (isGroup) {
|
|
13524
13657
|
if (!conversationId) return;
|
|
13525
13658
|
emitGroupReactionAdd({
|
|
13526
|
-
messageId,
|
|
13659
|
+
messageId: messageId2,
|
|
13527
13660
|
sender: loggedUserDetails._id,
|
|
13528
13661
|
reaction,
|
|
13529
13662
|
conversationId
|
|
@@ -13531,7 +13664,7 @@ function useMessageItemActions({
|
|
|
13531
13664
|
} else {
|
|
13532
13665
|
if (!receiver) return;
|
|
13533
13666
|
emitDmReactionAdd({
|
|
13534
|
-
messageId,
|
|
13667
|
+
messageId: messageId2,
|
|
13535
13668
|
sender: loggedUserDetails._id,
|
|
13536
13669
|
receiver,
|
|
13537
13670
|
reaction,
|
|
@@ -13541,7 +13674,7 @@ function useMessageItemActions({
|
|
|
13541
13674
|
}
|
|
13542
13675
|
};
|
|
13543
13676
|
const handlePinClick = () => {
|
|
13544
|
-
if (!
|
|
13677
|
+
if (!messageId2 || !loggedUserDetails) return;
|
|
13545
13678
|
if (isPinned) {
|
|
13546
13679
|
if (!isPinnedByMe) return;
|
|
13547
13680
|
if (isGroup) {
|
|
@@ -13549,14 +13682,14 @@ function useMessageItemActions({
|
|
|
13549
13682
|
emitGroupUnpin({
|
|
13550
13683
|
conversationId,
|
|
13551
13684
|
sender: loggedUserDetails._id,
|
|
13552
|
-
messageId,
|
|
13685
|
+
messageId: messageId2,
|
|
13553
13686
|
receiver: ""
|
|
13554
13687
|
});
|
|
13555
13688
|
} else {
|
|
13556
13689
|
emitDmUnpin({
|
|
13557
13690
|
conversationId,
|
|
13558
13691
|
sender: loggedUserDetails._id,
|
|
13559
|
-
messageId,
|
|
13692
|
+
messageId: messageId2,
|
|
13560
13693
|
receiver: receiver || ""
|
|
13561
13694
|
});
|
|
13562
13695
|
}
|
|
@@ -13566,32 +13699,32 @@ function useMessageItemActions({
|
|
|
13566
13699
|
emitGroupPin({
|
|
13567
13700
|
conversationId,
|
|
13568
13701
|
sender: loggedUserDetails._id,
|
|
13569
|
-
messageId,
|
|
13702
|
+
messageId: messageId2,
|
|
13570
13703
|
receiver: ""
|
|
13571
13704
|
});
|
|
13572
13705
|
} else {
|
|
13573
13706
|
emitDmPin({
|
|
13574
13707
|
conversationId,
|
|
13575
13708
|
sender: loggedUserDetails._id,
|
|
13576
|
-
messageId,
|
|
13709
|
+
messageId: messageId2,
|
|
13577
13710
|
receiver: receiver || ""
|
|
13578
13711
|
});
|
|
13579
13712
|
}
|
|
13580
13713
|
}
|
|
13581
13714
|
};
|
|
13582
13715
|
const handleStarClick = () => {
|
|
13583
|
-
if (!
|
|
13716
|
+
if (!messageId2 || !loggedUserDetails || !conversationId) return;
|
|
13584
13717
|
if (isStarred) {
|
|
13585
13718
|
if (isGroup) {
|
|
13586
|
-
emitGroupUnstar({ messageId, sender: loggedUserDetails._id, conversationId });
|
|
13719
|
+
emitGroupUnstar({ messageId: messageId2, sender: loggedUserDetails._id, conversationId });
|
|
13587
13720
|
} else {
|
|
13588
|
-
emitDmUnstar({ messageId, sender: loggedUserDetails._id, conversationId });
|
|
13721
|
+
emitDmUnstar({ messageId: messageId2, sender: loggedUserDetails._id, conversationId });
|
|
13589
13722
|
}
|
|
13590
13723
|
} else {
|
|
13591
13724
|
if (isGroup) {
|
|
13592
|
-
emitGroupStar({ messageId, sender: loggedUserDetails._id, conversationId });
|
|
13725
|
+
emitGroupStar({ messageId: messageId2, sender: loggedUserDetails._id, conversationId });
|
|
13593
13726
|
} else {
|
|
13594
|
-
emitDmStar({ messageId, sender: loggedUserDetails._id, conversationId });
|
|
13727
|
+
emitDmStar({ messageId: messageId2, sender: loggedUserDetails._id, conversationId });
|
|
13595
13728
|
}
|
|
13596
13729
|
}
|
|
13597
13730
|
};
|
|
@@ -13813,6 +13946,7 @@ function MessageItemTextBubble({
|
|
|
13813
13946
|
isForwarded,
|
|
13814
13947
|
showSenderLabel,
|
|
13815
13948
|
senderName,
|
|
13949
|
+
senderId,
|
|
13816
13950
|
replyTo,
|
|
13817
13951
|
loggedUserDetails,
|
|
13818
13952
|
allUsers,
|
|
@@ -13851,7 +13985,13 @@ function MessageItemTextBubble({
|
|
|
13851
13985
|
),
|
|
13852
13986
|
children: [
|
|
13853
13987
|
(canShowSenderName || isForwarded) && /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
13854
|
-
canShowSenderName ? /* @__PURE__ */ jsx(
|
|
13988
|
+
canShowSenderName ? /* @__PURE__ */ jsx(
|
|
13989
|
+
GroupSenderName,
|
|
13990
|
+
{
|
|
13991
|
+
name: senderName,
|
|
13992
|
+
colorSeed: senderId || senderName
|
|
13993
|
+
}
|
|
13994
|
+
) : null,
|
|
13855
13995
|
isForwarded ? /* @__PURE__ */ jsx(MessageForwardedLabel, { isSender, className: "px-0 pt-0 pb-0" }) : null
|
|
13856
13996
|
] }),
|
|
13857
13997
|
/* @__PURE__ */ jsx(
|
|
@@ -13902,7 +14042,7 @@ function MessageItemTextBubble({
|
|
|
13902
14042
|
}
|
|
13903
14043
|
)
|
|
13904
14044
|
] })
|
|
13905
|
-
] }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-
|
|
14045
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
13906
14046
|
hasText && /* @__PURE__ */ jsxs("p", { className: "whitespace-pre-wrap break-words leading-snug", children: [
|
|
13907
14047
|
message,
|
|
13908
14048
|
isEdited && /* @__PURE__ */ jsx(
|
|
@@ -13960,6 +14100,7 @@ function MessageItemAttachmentBubble({
|
|
|
13960
14100
|
isGroupedWithNext,
|
|
13961
14101
|
showSenderLabel,
|
|
13962
14102
|
senderName,
|
|
14103
|
+
senderId,
|
|
13963
14104
|
formattedTime,
|
|
13964
14105
|
status,
|
|
13965
14106
|
isPending,
|
|
@@ -14008,6 +14149,7 @@ function MessageItemAttachmentBubble({
|
|
|
14008
14149
|
isGroupedWithNext,
|
|
14009
14150
|
showSenderLabel,
|
|
14010
14151
|
senderName,
|
|
14152
|
+
senderId,
|
|
14011
14153
|
formattedTime,
|
|
14012
14154
|
status,
|
|
14013
14155
|
isPending,
|
|
@@ -14067,6 +14209,7 @@ function MessageItemView(props) {
|
|
|
14067
14209
|
isGroup,
|
|
14068
14210
|
isHighlighted,
|
|
14069
14211
|
senderName,
|
|
14212
|
+
senderId,
|
|
14070
14213
|
senderImage,
|
|
14071
14214
|
showSenderLabel,
|
|
14072
14215
|
senderAvatarImage,
|
|
@@ -14243,6 +14386,7 @@ function MessageItemView(props) {
|
|
|
14243
14386
|
isGroupedWithNext,
|
|
14244
14387
|
showSenderLabel,
|
|
14245
14388
|
senderName,
|
|
14389
|
+
senderId,
|
|
14246
14390
|
formattedTime,
|
|
14247
14391
|
status,
|
|
14248
14392
|
isPending,
|
|
@@ -14284,6 +14428,7 @@ function MessageItemView(props) {
|
|
|
14284
14428
|
isForwarded,
|
|
14285
14429
|
showSenderLabel,
|
|
14286
14430
|
senderName,
|
|
14431
|
+
senderId,
|
|
14287
14432
|
replyTo,
|
|
14288
14433
|
loggedUserDetails,
|
|
14289
14434
|
allUsers,
|
|
@@ -14474,6 +14619,28 @@ function MessageSelectionBar({
|
|
|
14474
14619
|
|
|
14475
14620
|
// src/chat/active-channel-messages/utils.ts
|
|
14476
14621
|
var getMessageSenderId2 = (msg) => msg ? String(msg.senderId || msg.sender?._id || "") : "";
|
|
14622
|
+
var isLikelyObjectId = (value) => /^[a-f\d]{24}$/i.test(value);
|
|
14623
|
+
function resolveGroupSenderDisplay(message, allUsers = [], participants = []) {
|
|
14624
|
+
const senderId = getMessageSenderId2(message);
|
|
14625
|
+
if (senderId) {
|
|
14626
|
+
const fromUsers = allUsers.find((user) => String(user._id) === senderId);
|
|
14627
|
+
if (fromUsers?.name?.trim()) {
|
|
14628
|
+
return { name: fromUsers.name.trim(), image: fromUsers.image };
|
|
14629
|
+
}
|
|
14630
|
+
const fromParticipants = participants.find((participant) => {
|
|
14631
|
+
const id = typeof participant === "string" ? participant : participant?._id;
|
|
14632
|
+
return String(id) === senderId;
|
|
14633
|
+
});
|
|
14634
|
+
if (fromParticipants && typeof fromParticipants === "object" && fromParticipants.name?.trim()) {
|
|
14635
|
+
return { name: fromParticipants.name.trim(), image: fromParticipants.image };
|
|
14636
|
+
}
|
|
14637
|
+
}
|
|
14638
|
+
const sender = message.sender;
|
|
14639
|
+
if (typeof sender === "string" && sender.trim() && !isLikelyObjectId(sender.trim())) {
|
|
14640
|
+
return { name: sender.trim(), image: message.senderImage };
|
|
14641
|
+
}
|
|
14642
|
+
return { name: "User", image: void 0 };
|
|
14643
|
+
}
|
|
14477
14644
|
var isSameMessageSide = (a, b, isGroupChat) => {
|
|
14478
14645
|
if (!!a.isOwnMessage !== !!b.isOwnMessage) return false;
|
|
14479
14646
|
if (a.isOwnMessage) return true;
|
|
@@ -14487,8 +14654,8 @@ function canDeleteSelectionForEveryone(selectedKeys, messages, isGroup) {
|
|
|
14487
14654
|
const parsed = [...selectedKeys].map((key) => parseSelectionKey(key));
|
|
14488
14655
|
const messageIds = new Set(parsed.map((entry) => entry.messageId));
|
|
14489
14656
|
if (messageIds.size !== 1) return false;
|
|
14490
|
-
const
|
|
14491
|
-
const message = messages.find((entry) => String(entry._id || entry.id) ===
|
|
14657
|
+
const messageId2 = [...messageIds][0];
|
|
14658
|
+
const message = messages.find((entry) => String(entry._id || entry.id) === messageId2);
|
|
14492
14659
|
if (!message?.isOwnMessage) return false;
|
|
14493
14660
|
if (!isWithinMessageEditWindow(message.timestamp, isGroup)) return false;
|
|
14494
14661
|
const hasAttachmentKey = parsed.some((entry) => entry.attachmentId);
|
|
@@ -14502,6 +14669,9 @@ function canDeleteSelectionForEveryone(selectedKeys, messages, isGroup) {
|
|
|
14502
14669
|
});
|
|
14503
14670
|
}
|
|
14504
14671
|
|
|
14672
|
+
// src/chat/active-channel-messages/ActiveChannelMessagesView.tsx
|
|
14673
|
+
init_useStore();
|
|
14674
|
+
|
|
14505
14675
|
// src/chat/active-channel-messages/useActiveChannelMessages.ts
|
|
14506
14676
|
init_useStore();
|
|
14507
14677
|
init_store_helpers();
|
|
@@ -14517,6 +14687,7 @@ function mapApiMessage(m, activeChannel, conversationId, loggedUserId, activeCon
|
|
|
14517
14687
|
content: m.content,
|
|
14518
14688
|
sender: m.sender?.name || "User",
|
|
14519
14689
|
senderId: String(m.sender?._id || m.sender || ""),
|
|
14690
|
+
senderImage: m.sender?.image,
|
|
14520
14691
|
receiver: activeChannel?.id,
|
|
14521
14692
|
timestamp: m.createdAt,
|
|
14522
14693
|
isOwnMessage: isOwn,
|
|
@@ -14544,7 +14715,101 @@ function mapApiMessage(m, activeChannel, conversationId, loggedUserId, activeCon
|
|
|
14544
14715
|
};
|
|
14545
14716
|
}
|
|
14546
14717
|
|
|
14718
|
+
// src/chat/active-channel-messages/jump-to-date.ts
|
|
14719
|
+
function startOfLocalDay(date) {
|
|
14720
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
|
|
14721
|
+
}
|
|
14722
|
+
function toDateInputValue(date) {
|
|
14723
|
+
const y = date.getFullYear();
|
|
14724
|
+
const m = String(date.getMonth() + 1).padStart(2, "0");
|
|
14725
|
+
const d = String(date.getDate()).padStart(2, "0");
|
|
14726
|
+
return `${y}-${m}-${d}`;
|
|
14727
|
+
}
|
|
14728
|
+
function clampJumpDate(picked, minDay, maxDay) {
|
|
14729
|
+
if (!Number.isFinite(minDay) || !Number.isFinite(maxDay) || minDay > maxDay) return null;
|
|
14730
|
+
const at = startOfLocalDay(picked);
|
|
14731
|
+
const clamped = Math.min(Math.max(at, minDay), maxDay);
|
|
14732
|
+
return new Date(clamped);
|
|
14733
|
+
}
|
|
14734
|
+
function resolveJumpDateBounds(createdAt, oldestMessageTimestamp, now = /* @__PURE__ */ new Date()) {
|
|
14735
|
+
const today = startOfLocalDay(now);
|
|
14736
|
+
const createdDay = createdAt ? startOfLocalDay(new Date(createdAt)) : null;
|
|
14737
|
+
const oldestDay = oldestMessageTimestamp ? startOfLocalDay(new Date(oldestMessageTimestamp)) : null;
|
|
14738
|
+
let minDay = today;
|
|
14739
|
+
if (createdDay != null && oldestDay != null) {
|
|
14740
|
+
minDay = Math.max(createdDay, oldestDay);
|
|
14741
|
+
} else if (oldestDay != null) {
|
|
14742
|
+
minDay = oldestDay;
|
|
14743
|
+
} else if (createdDay != null) {
|
|
14744
|
+
minDay = createdDay;
|
|
14745
|
+
}
|
|
14746
|
+
return { minDay: Math.min(minDay, today), maxDay: today };
|
|
14747
|
+
}
|
|
14748
|
+
function resolveJumpPreset(preset, now = /* @__PURE__ */ new Date()) {
|
|
14749
|
+
const day = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
14750
|
+
if (preset === "today") return day.getTime();
|
|
14751
|
+
if (preset === "yesterday") {
|
|
14752
|
+
day.setDate(day.getDate() - 1);
|
|
14753
|
+
return day.getTime();
|
|
14754
|
+
}
|
|
14755
|
+
if (preset === "lastWeek") {
|
|
14756
|
+
day.setDate(day.getDate() - 7);
|
|
14757
|
+
return day.getTime();
|
|
14758
|
+
}
|
|
14759
|
+
day.setMonth(day.getMonth() - 1);
|
|
14760
|
+
return day.getTime();
|
|
14761
|
+
}
|
|
14762
|
+
function messageId(m) {
|
|
14763
|
+
return String(m._id || m.id);
|
|
14764
|
+
}
|
|
14765
|
+
function findNearestMessageByDay(messages, targetDay) {
|
|
14766
|
+
let best = messages[0];
|
|
14767
|
+
let bestDist = Infinity;
|
|
14768
|
+
let bestDay = startOfLocalDay(new Date(best.timestamp));
|
|
14769
|
+
for (const m of messages) {
|
|
14770
|
+
const day = startOfLocalDay(new Date(m.timestamp));
|
|
14771
|
+
const dist = Math.abs(day - targetDay);
|
|
14772
|
+
if (dist < bestDist || dist === bestDist && day < bestDay) {
|
|
14773
|
+
best = m;
|
|
14774
|
+
bestDist = dist;
|
|
14775
|
+
bestDay = day;
|
|
14776
|
+
}
|
|
14777
|
+
}
|
|
14778
|
+
return best;
|
|
14779
|
+
}
|
|
14780
|
+
function resolveJumpStep(messages, pending, hasMore) {
|
|
14781
|
+
if (messages.length === 0) {
|
|
14782
|
+
return hasMore ? { action: "loadOlder" } : { action: "done" };
|
|
14783
|
+
}
|
|
14784
|
+
if (pending.kind === "beginning") {
|
|
14785
|
+
if (hasMore) return { action: "loadOlder" };
|
|
14786
|
+
return { action: "scroll", messageId: messageId(messages[0]) };
|
|
14787
|
+
}
|
|
14788
|
+
const oldestDay = startOfLocalDay(new Date(messages[0].timestamp));
|
|
14789
|
+
if (hasMore && oldestDay > pending.at) {
|
|
14790
|
+
return { action: "loadOlder" };
|
|
14791
|
+
}
|
|
14792
|
+
const onDay = messages.find(
|
|
14793
|
+
(m) => startOfLocalDay(new Date(m.timestamp)) === pending.at
|
|
14794
|
+
);
|
|
14795
|
+
if (onDay) {
|
|
14796
|
+
return { action: "scroll", messageId: messageId(onDay) };
|
|
14797
|
+
}
|
|
14798
|
+
const nearest = findNearestMessageByDay(messages, pending.at);
|
|
14799
|
+
return { action: "scroll", messageId: messageId(nearest) };
|
|
14800
|
+
}
|
|
14801
|
+
function smoothScrollToMessage(container, messageEl) {
|
|
14802
|
+
const containerRect = container.getBoundingClientRect();
|
|
14803
|
+
const messageRect = messageEl.getBoundingClientRect();
|
|
14804
|
+
const delta = messageRect.top - containerRect.top - Math.min(120, container.clientHeight * 0.25);
|
|
14805
|
+
container.scrollTo({
|
|
14806
|
+
top: Math.max(0, container.scrollTop + delta),
|
|
14807
|
+
behavior: "smooth"
|
|
14808
|
+
});
|
|
14809
|
+
}
|
|
14810
|
+
|
|
14547
14811
|
// src/chat/active-channel-messages/useActiveChannelMessages.ts
|
|
14812
|
+
var MAX_JUMP_OLDER_PAGES = 40;
|
|
14548
14813
|
function useActiveChannelMessages({
|
|
14549
14814
|
activeChannel,
|
|
14550
14815
|
loggedUserId,
|
|
@@ -14567,6 +14832,11 @@ function useActiveChannelMessages({
|
|
|
14567
14832
|
const previousMessageCountRef = useRef(0);
|
|
14568
14833
|
const previousLastMessageIdRef = useRef(null);
|
|
14569
14834
|
const [enteringMessageIds, setEnteringMessageIds] = useState(/* @__PURE__ */ new Set());
|
|
14835
|
+
const [showScrollToBottom, setShowScrollToBottom] = useState(false);
|
|
14836
|
+
const stickToBottomRef = useRef(true);
|
|
14837
|
+
const pendingJumpRef = useRef(null);
|
|
14838
|
+
const jumpPagesRef = useRef(0);
|
|
14839
|
+
const [jumpNonce, setJumpNonce] = useState(0);
|
|
14570
14840
|
const { fetchMessages: fetchMessages2, messagesMetadata, deletedForMeIds, searchedMessageId, isSearchActive, setSearchActive, setSearchedMessageId, fetchSearchMessageContext } = useStore();
|
|
14571
14841
|
const loggedUserImage = useStore((s) => s.loggedUserDetails?.image);
|
|
14572
14842
|
const conversations = useStore((s) => s.conversations);
|
|
@@ -14590,6 +14860,13 @@ function useActiveChannelMessages({
|
|
|
14590
14860
|
})),
|
|
14591
14861
|
[displayMessages, messagesById, loggedUserId]
|
|
14592
14862
|
);
|
|
14863
|
+
const jumpDateBounds = useMemo(
|
|
14864
|
+
() => resolveJumpDateBounds(
|
|
14865
|
+
conversationInfo?.createdAt,
|
|
14866
|
+
displayMessages[0]?.timestamp
|
|
14867
|
+
),
|
|
14868
|
+
[conversationInfo?.createdAt, displayMessages]
|
|
14869
|
+
);
|
|
14593
14870
|
useEffect(() => {
|
|
14594
14871
|
const messages = messagesWithResolvedReplies;
|
|
14595
14872
|
const lastMessage = messages[messages.length - 1];
|
|
@@ -14627,6 +14904,10 @@ function useActiveChannelMessages({
|
|
|
14627
14904
|
previousMessageCountRef.current = 0;
|
|
14628
14905
|
previousLastMessageIdRef.current = null;
|
|
14629
14906
|
setEnteringMessageIds(/* @__PURE__ */ new Set());
|
|
14907
|
+
pendingJumpRef.current = null;
|
|
14908
|
+
jumpPagesRef.current = 0;
|
|
14909
|
+
stickToBottomRef.current = true;
|
|
14910
|
+
setShowScrollToBottom(false);
|
|
14630
14911
|
}, [conversationId, clearSelection]);
|
|
14631
14912
|
const onSelectionModeChangeRef = useRef(onSelectionModeChange);
|
|
14632
14913
|
useEffect(() => {
|
|
@@ -14636,10 +14917,10 @@ function useActiveChannelMessages({
|
|
|
14636
14917
|
onSelectionModeChangeRef.current?.(selectionMode);
|
|
14637
14918
|
}, [selectionMode]);
|
|
14638
14919
|
const toggleSelection = useCallback((message, attachmentId) => {
|
|
14639
|
-
const
|
|
14640
|
-
if (!
|
|
14920
|
+
const messageId2 = String(message._id || message.id);
|
|
14921
|
+
if (!messageId2) return;
|
|
14641
14922
|
const useAttachmentSelection = messageUsesAttachmentSelection(message);
|
|
14642
|
-
const key = useAttachmentSelection && attachmentId ? buildSelectionKey(
|
|
14923
|
+
const key = useAttachmentSelection && attachmentId ? buildSelectionKey(messageId2, attachmentId) : messageId2;
|
|
14643
14924
|
setSelectedKeys((prev) => {
|
|
14644
14925
|
const next = new Set(prev);
|
|
14645
14926
|
if (next.has(key)) next.delete(key);
|
|
@@ -14649,17 +14930,17 @@ function useActiveChannelMessages({
|
|
|
14649
14930
|
});
|
|
14650
14931
|
}, []);
|
|
14651
14932
|
const enterSelectionMode = useCallback((message, attachmentId) => {
|
|
14652
|
-
const
|
|
14653
|
-
if (!
|
|
14933
|
+
const messageId2 = String(message._id || message.id);
|
|
14934
|
+
if (!messageId2) return;
|
|
14654
14935
|
setSelectionMode(true);
|
|
14655
14936
|
const useAttachmentSelection = messageUsesAttachmentSelection(message);
|
|
14656
14937
|
if (useAttachmentSelection) {
|
|
14657
14938
|
if (attachmentId) {
|
|
14658
|
-
setSelectedKeys((prev) => new Set(prev).add(buildSelectionKey(
|
|
14939
|
+
setSelectedKeys((prev) => new Set(prev).add(buildSelectionKey(messageId2, attachmentId)));
|
|
14659
14940
|
}
|
|
14660
14941
|
return;
|
|
14661
14942
|
}
|
|
14662
|
-
setSelectedKeys((prev) => new Set(prev).add(
|
|
14943
|
+
setSelectedKeys((prev) => new Set(prev).add(messageId2));
|
|
14663
14944
|
}, []);
|
|
14664
14945
|
const selectedForwardItems = resolveForwardItems(selectedKeys, displayMessages);
|
|
14665
14946
|
const canDeleteForEveryone = useMemo(
|
|
@@ -14678,14 +14959,14 @@ function useActiveChannelMessages({
|
|
|
14678
14959
|
}
|
|
14679
14960
|
const isGroupChat = !!activeChannel?.isGroup;
|
|
14680
14961
|
selectedKeys.forEach((key) => {
|
|
14681
|
-
const { messageId, attachmentId } = parseSelectionKey(key);
|
|
14682
|
-
if (!
|
|
14683
|
-
const message = displayMessages.find((entry) => String(entry._id || entry.id) ===
|
|
14962
|
+
const { messageId: messageId2, attachmentId } = parseSelectionKey(key);
|
|
14963
|
+
if (!messageId2 || messageId2.startsWith("temp-")) return;
|
|
14964
|
+
const message = displayMessages.find((entry) => String(entry._id || entry.id) === messageId2);
|
|
14684
14965
|
if (isGroupChat) {
|
|
14685
14966
|
const convId = String(message?.conversationId || conversationId || "");
|
|
14686
14967
|
if (!convId) return;
|
|
14687
14968
|
emitGroupDelete({
|
|
14688
|
-
messageId,
|
|
14969
|
+
messageId: messageId2,
|
|
14689
14970
|
sender: loggedUserDetails._id,
|
|
14690
14971
|
deleteType,
|
|
14691
14972
|
conversationId: convId,
|
|
@@ -14695,7 +14976,7 @@ function useActiveChannelMessages({
|
|
|
14695
14976
|
const receiver = message?.receiver || activeChannel?.id;
|
|
14696
14977
|
if (!receiver) return;
|
|
14697
14978
|
emitDmDelete({
|
|
14698
|
-
messageId,
|
|
14979
|
+
messageId: messageId2,
|
|
14699
14980
|
sender: loggedUserDetails._id,
|
|
14700
14981
|
receiver: String(receiver),
|
|
14701
14982
|
deleteType,
|
|
@@ -14734,43 +15015,138 @@ function useActiveChannelMessages({
|
|
|
14734
15015
|
fetchMessages2(conversationId);
|
|
14735
15016
|
}
|
|
14736
15017
|
};
|
|
14737
|
-
const handleReplyTargetClick = async (
|
|
14738
|
-
if (!
|
|
14739
|
-
|
|
14740
|
-
|
|
15018
|
+
const handleReplyTargetClick = async (messageId2) => {
|
|
15019
|
+
if (!messageId2) return;
|
|
15020
|
+
stickToBottomRef.current = false;
|
|
15021
|
+
if (messagesById.has(messageId2)) {
|
|
15022
|
+
setSearchedMessageId(messageId2);
|
|
14741
15023
|
return;
|
|
14742
15024
|
}
|
|
14743
|
-
await fetchSearchMessageContext(
|
|
15025
|
+
await fetchSearchMessageContext(messageId2, { searchMode: false });
|
|
14744
15026
|
};
|
|
15027
|
+
const handleJumpTo = useCallback((preset, specificDate) => {
|
|
15028
|
+
stickToBottomRef.current = false;
|
|
15029
|
+
if (preset === "beginning") {
|
|
15030
|
+
pendingJumpRef.current = { kind: "beginning" };
|
|
15031
|
+
} else if (preset === "specific") {
|
|
15032
|
+
if (!specificDate) return;
|
|
15033
|
+
const clamped = clampJumpDate(
|
|
15034
|
+
specificDate,
|
|
15035
|
+
jumpDateBounds.minDay,
|
|
15036
|
+
jumpDateBounds.maxDay
|
|
15037
|
+
);
|
|
15038
|
+
if (!clamped) return;
|
|
15039
|
+
pendingJumpRef.current = { kind: "date", at: startOfLocalDay(clamped) };
|
|
15040
|
+
} else {
|
|
15041
|
+
const raw = resolveJumpPreset(preset);
|
|
15042
|
+
const at = Math.min(Math.max(raw, jumpDateBounds.minDay), jumpDateBounds.maxDay);
|
|
15043
|
+
pendingJumpRef.current = { kind: "date", at };
|
|
15044
|
+
}
|
|
15045
|
+
jumpPagesRef.current = 0;
|
|
15046
|
+
setJumpNonce((n) => n + 1);
|
|
15047
|
+
}, [jumpDateBounds.minDay, jumpDateBounds.maxDay]);
|
|
15048
|
+
useEffect(() => {
|
|
15049
|
+
const pending = pendingJumpRef.current;
|
|
15050
|
+
if (!pending || isLoading) return;
|
|
15051
|
+
const step = resolveJumpStep(
|
|
15052
|
+
messagesWithResolvedReplies,
|
|
15053
|
+
pending,
|
|
15054
|
+
!!currentMeta?.hasMore
|
|
15055
|
+
);
|
|
15056
|
+
if (step.action === "loadOlder") {
|
|
15057
|
+
if (!conversationId || !currentMeta?.nextCursor || jumpPagesRef.current >= MAX_JUMP_OLDER_PAGES) {
|
|
15058
|
+
pendingJumpRef.current = null;
|
|
15059
|
+
const fallback = messagesWithResolvedReplies[0];
|
|
15060
|
+
if (fallback) setSearchedMessageId(String(fallback._id || fallback.id));
|
|
15061
|
+
return;
|
|
15062
|
+
}
|
|
15063
|
+
jumpPagesRef.current += 1;
|
|
15064
|
+
const prevScrollHeight = scrollContainerRef.current?.scrollHeight ?? 0;
|
|
15065
|
+
fetchMessages2(conversationId, DEFAULT_MESSAGES_LIMIT, currentMeta.nextCursor).then(() => {
|
|
15066
|
+
if (scrollContainerRef.current && prevScrollHeight) {
|
|
15067
|
+
scrollContainerRef.current.scrollTop = scrollContainerRef.current.scrollHeight - prevScrollHeight;
|
|
15068
|
+
}
|
|
15069
|
+
});
|
|
15070
|
+
return;
|
|
15071
|
+
}
|
|
15072
|
+
pendingJumpRef.current = null;
|
|
15073
|
+
if (step.action === "scroll") {
|
|
15074
|
+
setSearchedMessageId(null);
|
|
15075
|
+
requestAnimationFrame(() => setSearchedMessageId(step.messageId));
|
|
15076
|
+
}
|
|
15077
|
+
}, [
|
|
15078
|
+
jumpNonce,
|
|
15079
|
+
isLoading,
|
|
15080
|
+
messagesWithResolvedReplies,
|
|
15081
|
+
currentMeta?.hasMore,
|
|
15082
|
+
currentMeta?.nextCursor,
|
|
15083
|
+
conversationId,
|
|
15084
|
+
fetchMessages2,
|
|
15085
|
+
setSearchedMessageId
|
|
15086
|
+
]);
|
|
15087
|
+
const updateScrollToBottomVisibility = useCallback((el) => {
|
|
15088
|
+
const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
15089
|
+
const nearBottom = distanceFromBottom <= 96;
|
|
15090
|
+
stickToBottomRef.current = nearBottom;
|
|
15091
|
+
setShowScrollToBottom(!nearBottom);
|
|
15092
|
+
}, []);
|
|
15093
|
+
const handleScrollToBottom = useCallback(() => {
|
|
15094
|
+
stickToBottomRef.current = true;
|
|
15095
|
+
if (isSearchActive) {
|
|
15096
|
+
setSearchActive(false);
|
|
15097
|
+
setSearchedMessageId(null);
|
|
15098
|
+
if (conversationId) fetchMessages2(conversationId);
|
|
15099
|
+
setShowScrollToBottom(false);
|
|
15100
|
+
return;
|
|
15101
|
+
}
|
|
15102
|
+
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
15103
|
+
setShowScrollToBottom(false);
|
|
15104
|
+
}, [isSearchActive, conversationId, setSearchActive, setSearchedMessageId, fetchMessages2]);
|
|
14745
15105
|
const handleScroll = (e) => {
|
|
14746
15106
|
const target = e.currentTarget;
|
|
15107
|
+
updateScrollToBottomVisibility(target);
|
|
15108
|
+
if (pendingJumpRef.current) return;
|
|
14747
15109
|
if (target.scrollTop === 0 && currentMeta?.hasMore && !isLoading && conversationId && currentMeta.nextCursor) {
|
|
14748
15110
|
const prevScrollHeight = target.scrollHeight;
|
|
14749
15111
|
fetchMessages2(conversationId, DEFAULT_MESSAGES_LIMIT, currentMeta.nextCursor).then(() => {
|
|
14750
15112
|
if (scrollContainerRef.current) {
|
|
14751
15113
|
const newScrollHeight = scrollContainerRef.current.scrollHeight;
|
|
14752
15114
|
scrollContainerRef.current.scrollTop = newScrollHeight - prevScrollHeight;
|
|
15115
|
+
updateScrollToBottomVisibility(scrollContainerRef.current);
|
|
14753
15116
|
}
|
|
14754
15117
|
});
|
|
14755
15118
|
}
|
|
14756
15119
|
};
|
|
14757
15120
|
useLayoutEffect(() => {
|
|
14758
|
-
if (!isInitialLoading &&
|
|
15121
|
+
if (!isInitialLoading && stickToBottomRef.current && !pendingJumpRef.current) {
|
|
14759
15122
|
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
14760
15123
|
}
|
|
14761
|
-
}, [messagesWithResolvedReplies.length, isInitialLoading
|
|
15124
|
+
}, [messagesWithResolvedReplies.length, isInitialLoading]);
|
|
14762
15125
|
useEffect(() => {
|
|
14763
15126
|
if (searchedMessageId && !isLoading) {
|
|
15127
|
+
stickToBottomRef.current = false;
|
|
15128
|
+
const container = scrollContainerRef.current;
|
|
14764
15129
|
const element = document.getElementById(`message-${searchedMessageId}`);
|
|
14765
|
-
if (element) {
|
|
14766
|
-
|
|
15130
|
+
if (container && element) {
|
|
15131
|
+
requestAnimationFrame(() => {
|
|
15132
|
+
requestAnimationFrame(() => {
|
|
15133
|
+
smoothScrollToMessage(container, element);
|
|
15134
|
+
updateScrollToBottomVisibility(container);
|
|
15135
|
+
});
|
|
15136
|
+
});
|
|
14767
15137
|
}
|
|
14768
15138
|
if (!isSearchActive) {
|
|
14769
15139
|
const timer = window.setTimeout(() => setSearchedMessageId(null), 2500);
|
|
14770
15140
|
return () => window.clearTimeout(timer);
|
|
14771
15141
|
}
|
|
14772
15142
|
}
|
|
14773
|
-
}, [
|
|
15143
|
+
}, [
|
|
15144
|
+
searchedMessageId,
|
|
15145
|
+
isLoading,
|
|
15146
|
+
isSearchActive,
|
|
15147
|
+
setSearchedMessageId,
|
|
15148
|
+
updateScrollToBottomVisibility
|
|
15149
|
+
]);
|
|
14774
15150
|
return {
|
|
14775
15151
|
activeChannel,
|
|
14776
15152
|
conversationId,
|
|
@@ -14796,11 +15172,297 @@ function useActiveChannelMessages({
|
|
|
14796
15172
|
canDeleteForEveryone,
|
|
14797
15173
|
handleResetToNormal,
|
|
14798
15174
|
handleReplyTargetClick,
|
|
15175
|
+
handleJumpTo,
|
|
15176
|
+
jumpDateBounds,
|
|
15177
|
+
showScrollToBottom,
|
|
15178
|
+
handleScrollToBottom,
|
|
14799
15179
|
handleScroll
|
|
14800
15180
|
};
|
|
14801
15181
|
}
|
|
15182
|
+
function Calendar({
|
|
15183
|
+
className,
|
|
15184
|
+
classNames,
|
|
15185
|
+
showOutsideDays = true,
|
|
15186
|
+
captionLayout = "label",
|
|
15187
|
+
buttonVariant = "ghost",
|
|
15188
|
+
formatters,
|
|
15189
|
+
components,
|
|
15190
|
+
...props
|
|
15191
|
+
}) {
|
|
15192
|
+
const defaultClassNames = getDefaultClassNames();
|
|
15193
|
+
return /* @__PURE__ */ jsx(
|
|
15194
|
+
DayPicker,
|
|
15195
|
+
{
|
|
15196
|
+
showOutsideDays,
|
|
15197
|
+
className: cn(
|
|
15198
|
+
"group/calendar bg-background p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
|
|
15199
|
+
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
|
15200
|
+
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
|
|
15201
|
+
className
|
|
15202
|
+
),
|
|
15203
|
+
captionLayout,
|
|
15204
|
+
formatters: {
|
|
15205
|
+
formatMonthDropdown: (date) => date.toLocaleString("default", { month: "short" }),
|
|
15206
|
+
...formatters
|
|
15207
|
+
},
|
|
15208
|
+
classNames: {
|
|
15209
|
+
root: cn("w-fit", defaultClassNames.root),
|
|
15210
|
+
months: cn(
|
|
15211
|
+
"relative flex flex-col gap-4 md:flex-row",
|
|
15212
|
+
defaultClassNames.months
|
|
15213
|
+
),
|
|
15214
|
+
month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
|
|
15215
|
+
nav: cn(
|
|
15216
|
+
"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
|
|
15217
|
+
defaultClassNames.nav
|
|
15218
|
+
),
|
|
15219
|
+
button_previous: cn(
|
|
15220
|
+
buttonVariants({ variant: buttonVariant }),
|
|
15221
|
+
"size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
|
|
15222
|
+
defaultClassNames.button_previous
|
|
15223
|
+
),
|
|
15224
|
+
button_next: cn(
|
|
15225
|
+
buttonVariants({ variant: buttonVariant }),
|
|
15226
|
+
"size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
|
|
15227
|
+
defaultClassNames.button_next
|
|
15228
|
+
),
|
|
15229
|
+
month_caption: cn(
|
|
15230
|
+
"flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)",
|
|
15231
|
+
defaultClassNames.month_caption
|
|
15232
|
+
),
|
|
15233
|
+
dropdowns: cn(
|
|
15234
|
+
"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium",
|
|
15235
|
+
defaultClassNames.dropdowns
|
|
15236
|
+
),
|
|
15237
|
+
dropdown_root: cn(
|
|
15238
|
+
"relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50",
|
|
15239
|
+
defaultClassNames.dropdown_root
|
|
15240
|
+
),
|
|
15241
|
+
dropdown: cn(
|
|
15242
|
+
"absolute inset-0 bg-popover opacity-0",
|
|
15243
|
+
defaultClassNames.dropdown
|
|
15244
|
+
),
|
|
15245
|
+
caption_label: cn(
|
|
15246
|
+
"font-medium select-none",
|
|
15247
|
+
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",
|
|
15248
|
+
defaultClassNames.caption_label
|
|
15249
|
+
),
|
|
15250
|
+
month_grid: cn("w-full border-collapse", defaultClassNames.month_grid),
|
|
15251
|
+
weekdays: cn("flex", defaultClassNames.weekdays),
|
|
15252
|
+
weekday: cn(
|
|
15253
|
+
"flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none",
|
|
15254
|
+
defaultClassNames.weekday
|
|
15255
|
+
),
|
|
15256
|
+
week: cn("mt-2 flex w-full", defaultClassNames.week),
|
|
15257
|
+
week_number_header: cn(
|
|
15258
|
+
"w-(--cell-size) select-none",
|
|
15259
|
+
defaultClassNames.week_number_header
|
|
15260
|
+
),
|
|
15261
|
+
week_number: cn(
|
|
15262
|
+
"text-[0.8rem] text-muted-foreground select-none",
|
|
15263
|
+
defaultClassNames.week_number
|
|
15264
|
+
),
|
|
15265
|
+
day: cn(
|
|
15266
|
+
"group/day relative aspect-square h-full w-full p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-md",
|
|
15267
|
+
props.showWeekNumber ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-md" : "[&:first-child[data-selected=true]_button]:rounded-l-md",
|
|
15268
|
+
defaultClassNames.day
|
|
15269
|
+
),
|
|
15270
|
+
range_start: cn(
|
|
15271
|
+
"rounded-l-md bg-accent",
|
|
15272
|
+
defaultClassNames.range_start
|
|
15273
|
+
),
|
|
15274
|
+
range_middle: cn("rounded-none", defaultClassNames.range_middle),
|
|
15275
|
+
range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
|
|
15276
|
+
today: cn(
|
|
15277
|
+
"rounded-md bg-accent text-accent-foreground data-[selected=true]:rounded-none",
|
|
15278
|
+
defaultClassNames.today
|
|
15279
|
+
),
|
|
15280
|
+
outside: cn(
|
|
15281
|
+
"text-muted-foreground aria-selected:text-muted-foreground",
|
|
15282
|
+
defaultClassNames.outside
|
|
15283
|
+
),
|
|
15284
|
+
disabled: cn(
|
|
15285
|
+
"text-muted-foreground opacity-50",
|
|
15286
|
+
defaultClassNames.disabled
|
|
15287
|
+
),
|
|
15288
|
+
hidden: cn("invisible", defaultClassNames.hidden),
|
|
15289
|
+
...classNames
|
|
15290
|
+
},
|
|
15291
|
+
components: {
|
|
15292
|
+
Root: ({ className: className2, rootRef, ...props2 }) => {
|
|
15293
|
+
return /* @__PURE__ */ jsx(
|
|
15294
|
+
"div",
|
|
15295
|
+
{
|
|
15296
|
+
"data-slot": "calendar",
|
|
15297
|
+
ref: rootRef,
|
|
15298
|
+
className: cn(className2),
|
|
15299
|
+
...props2
|
|
15300
|
+
}
|
|
15301
|
+
);
|
|
15302
|
+
},
|
|
15303
|
+
Chevron: ({ className: className2, orientation, ...props2 }) => {
|
|
15304
|
+
if (orientation === "left") {
|
|
15305
|
+
return /* @__PURE__ */ jsx(ChevronLeftIcon, { className: cn("size-4", className2), ...props2 });
|
|
15306
|
+
}
|
|
15307
|
+
if (orientation === "right") {
|
|
15308
|
+
return /* @__PURE__ */ jsx(
|
|
15309
|
+
ChevronRightIcon,
|
|
15310
|
+
{
|
|
15311
|
+
className: cn("size-4", className2),
|
|
15312
|
+
...props2
|
|
15313
|
+
}
|
|
15314
|
+
);
|
|
15315
|
+
}
|
|
15316
|
+
return /* @__PURE__ */ jsx(ChevronDownIcon, { className: cn("size-4", className2), ...props2 });
|
|
15317
|
+
},
|
|
15318
|
+
DayButton: CalendarDayButton,
|
|
15319
|
+
WeekNumber: ({ children, ...props2 }) => {
|
|
15320
|
+
return /* @__PURE__ */ jsx("td", { ...props2, children: /* @__PURE__ */ jsx("div", { className: "flex size-(--cell-size) items-center justify-center text-center", children }) });
|
|
15321
|
+
},
|
|
15322
|
+
...components
|
|
15323
|
+
},
|
|
15324
|
+
...props
|
|
15325
|
+
}
|
|
15326
|
+
);
|
|
15327
|
+
}
|
|
15328
|
+
function CalendarDayButton({
|
|
15329
|
+
className,
|
|
15330
|
+
day,
|
|
15331
|
+
modifiers,
|
|
15332
|
+
...props
|
|
15333
|
+
}) {
|
|
15334
|
+
const defaultClassNames = getDefaultClassNames();
|
|
15335
|
+
const ref = React2.useRef(null);
|
|
15336
|
+
React2.useEffect(() => {
|
|
15337
|
+
if (modifiers.focused) ref.current?.focus();
|
|
15338
|
+
}, [modifiers.focused]);
|
|
15339
|
+
return /* @__PURE__ */ jsx(
|
|
15340
|
+
Button,
|
|
15341
|
+
{
|
|
15342
|
+
ref,
|
|
15343
|
+
variant: "ghost",
|
|
15344
|
+
size: "icon",
|
|
15345
|
+
"data-day": day.date.toLocaleDateString(),
|
|
15346
|
+
"data-selected-single": modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle,
|
|
15347
|
+
"data-range-start": modifiers.range_start,
|
|
15348
|
+
"data-range-end": modifiers.range_end,
|
|
15349
|
+
"data-range-middle": modifiers.range_middle,
|
|
15350
|
+
className: cn(
|
|
15351
|
+
"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",
|
|
15352
|
+
defaultClassNames.day,
|
|
15353
|
+
className
|
|
15354
|
+
),
|
|
15355
|
+
...props
|
|
15356
|
+
}
|
|
15357
|
+
);
|
|
15358
|
+
}
|
|
15359
|
+
var PRESETS = [
|
|
15360
|
+
{ preset: "today", label: "Today" },
|
|
15361
|
+
{ preset: "yesterday", label: "Yesterday" },
|
|
15362
|
+
{ preset: "lastWeek", label: "Last week" },
|
|
15363
|
+
{ preset: "lastMonth", label: "Last month" },
|
|
15364
|
+
{ preset: "beginning", label: "The very beginning" }
|
|
15365
|
+
];
|
|
15366
|
+
function ChatDateJumpMenu({ label, minDay, maxDay, onJump }) {
|
|
15367
|
+
const { scopeClassName } = useChatTheme();
|
|
15368
|
+
const [open, setOpen] = useState(false);
|
|
15369
|
+
const [showCalendar, setShowCalendar] = useState(false);
|
|
15370
|
+
const [calendarMonth, setCalendarMonth] = useState(() => new Date(maxDay));
|
|
15371
|
+
const minDate = new Date(minDay);
|
|
15372
|
+
const maxDate = new Date(maxDay);
|
|
15373
|
+
useEffect(() => {
|
|
15374
|
+
if (showCalendar) setCalendarMonth(new Date(maxDay));
|
|
15375
|
+
}, [showCalendar, maxDay]);
|
|
15376
|
+
const queueJump = (preset, specificDate) => {
|
|
15377
|
+
window.setTimeout(() => onJump(preset, specificDate), 0);
|
|
15378
|
+
};
|
|
15379
|
+
const handleOpenChange = (next) => {
|
|
15380
|
+
setOpen(next);
|
|
15381
|
+
if (!next) setShowCalendar(false);
|
|
15382
|
+
};
|
|
15383
|
+
const handlePreset = (preset) => {
|
|
15384
|
+
setOpen(false);
|
|
15385
|
+
setShowCalendar(false);
|
|
15386
|
+
queueJump(preset);
|
|
15387
|
+
};
|
|
15388
|
+
const handleDateSelect = (date) => {
|
|
15389
|
+
if (!date) return;
|
|
15390
|
+
const clamped = clampJumpDate(date, minDay, maxDay);
|
|
15391
|
+
if (!clamped) return;
|
|
15392
|
+
setOpen(false);
|
|
15393
|
+
setShowCalendar(false);
|
|
15394
|
+
queueJump("specific", clamped);
|
|
15395
|
+
};
|
|
15396
|
+
return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
|
|
15397
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
15398
|
+
"button",
|
|
15399
|
+
{
|
|
15400
|
+
type: "button",
|
|
15401
|
+
className: "chat-date-divider-pill chat-date-divider-pill--interactive",
|
|
15402
|
+
"aria-label": `Jump to date, currently ${label}`,
|
|
15403
|
+
children: [
|
|
15404
|
+
/* @__PURE__ */ jsx("span", { children: label }),
|
|
15405
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: "chat-date-divider-chevron", "aria-hidden": true })
|
|
15406
|
+
]
|
|
15407
|
+
}
|
|
15408
|
+
) }),
|
|
15409
|
+
/* @__PURE__ */ jsx(
|
|
15410
|
+
PopoverContent,
|
|
15411
|
+
{
|
|
15412
|
+
align: "center",
|
|
15413
|
+
sideOffset: 8,
|
|
15414
|
+
className: cn(
|
|
15415
|
+
scopeClassName,
|
|
15416
|
+
chatPopoverContentClass,
|
|
15417
|
+
"w-auto overflow-hidden rounded-2xl p-0",
|
|
15418
|
+
showCalendar ? "min-w-[300px]" : "min-w-[220px]"
|
|
15419
|
+
),
|
|
15420
|
+
onCloseAutoFocus: (event) => event.preventDefault(),
|
|
15421
|
+
children: showCalendar ? /* @__PURE__ */ jsx("div", { className: "p-2", children: /* @__PURE__ */ jsx(
|
|
15422
|
+
Calendar,
|
|
15423
|
+
{
|
|
15424
|
+
mode: "single",
|
|
15425
|
+
month: calendarMonth,
|
|
15426
|
+
onMonthChange: setCalendarMonth,
|
|
15427
|
+
startMonth: minDate,
|
|
15428
|
+
endMonth: maxDate,
|
|
15429
|
+
showOutsideDays: false,
|
|
15430
|
+
disabled: { before: minDate, after: maxDate },
|
|
15431
|
+
onSelect: handleDateSelect,
|
|
15432
|
+
className: "chat-jump-calendar rounded-xl bg-transparent p-1 [--cell-size:2.125rem]"
|
|
15433
|
+
}
|
|
15434
|
+
) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
15435
|
+
/* @__PURE__ */ jsxs("div", { className: "px-3 pt-3 pb-2", children: [
|
|
15436
|
+
/* @__PURE__ */ jsx("p", { className: chatOptionsMenuLabelClass, children: "Jump to\u2026" }),
|
|
15437
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1 flex flex-col", children: PRESETS.map(({ preset, label: itemLabel }) => /* @__PURE__ */ jsx(
|
|
15438
|
+
"button",
|
|
15439
|
+
{
|
|
15440
|
+
type: "button",
|
|
15441
|
+
className: cn(chatOptionsMenuItemClass, "w-full border-0 bg-transparent text-left"),
|
|
15442
|
+
onClick: () => handlePreset(preset),
|
|
15443
|
+
children: itemLabel
|
|
15444
|
+
},
|
|
15445
|
+
preset
|
|
15446
|
+
)) })
|
|
15447
|
+
] }),
|
|
15448
|
+
/* @__PURE__ */ jsx("div", { className: cn(chatOptionsMenuSeparatorClass, "mx-3") }),
|
|
15449
|
+
/* @__PURE__ */ jsx("div", { className: "px-1 pb-2", children: /* @__PURE__ */ jsx(
|
|
15450
|
+
"button",
|
|
15451
|
+
{
|
|
15452
|
+
type: "button",
|
|
15453
|
+
className: cn(chatOptionsMenuItemClass, "w-full border-0 bg-transparent text-left"),
|
|
15454
|
+
onClick: () => setShowCalendar(true),
|
|
15455
|
+
children: "Jump to a specific date"
|
|
15456
|
+
}
|
|
15457
|
+
) })
|
|
15458
|
+
] })
|
|
15459
|
+
}
|
|
15460
|
+
)
|
|
15461
|
+
] });
|
|
15462
|
+
}
|
|
14802
15463
|
var ActiveChannelMessagesView = (props) => {
|
|
14803
15464
|
const { formatDateDivider } = useChatLocale();
|
|
15465
|
+
const allUsers = useStore((s) => s.allUsers);
|
|
14804
15466
|
const {
|
|
14805
15467
|
activeChannel,
|
|
14806
15468
|
conversationId,
|
|
@@ -14826,6 +15488,10 @@ var ActiveChannelMessagesView = (props) => {
|
|
|
14826
15488
|
canDeleteForEveryone,
|
|
14827
15489
|
handleResetToNormal,
|
|
14828
15490
|
handleReplyTargetClick,
|
|
15491
|
+
handleJumpTo,
|
|
15492
|
+
jumpDateBounds,
|
|
15493
|
+
showScrollToBottom,
|
|
15494
|
+
handleScrollToBottom,
|
|
14829
15495
|
handleScroll
|
|
14830
15496
|
} = useActiveChannelMessages(props);
|
|
14831
15497
|
const { onReply, onForward } = props;
|
|
@@ -14838,7 +15504,7 @@ var ActiveChannelMessagesView = (props) => {
|
|
|
14838
15504
|
] })
|
|
14839
15505
|
] });
|
|
14840
15506
|
}
|
|
14841
|
-
return /* @__PURE__ */ jsxs("div", { className: "chat-message-canvas relative flex h-full
|
|
15507
|
+
return /* @__PURE__ */ jsxs("div", { className: "chat-message-canvas relative flex h-full flex-col", children: [
|
|
14842
15508
|
isSearchActive && /* @__PURE__ */ 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__ */ 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: [
|
|
14843
15509
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 bg-(--chat-theme) px-4 py-2.5", children: [
|
|
14844
15510
|
/* @__PURE__ */ jsx(History, { className: "size-3.5 animate-pulse text-white" }),
|
|
@@ -14875,11 +15541,20 @@ var ActiveChannelMessagesView = (props) => {
|
|
|
14875
15541
|
return groups;
|
|
14876
15542
|
}, {})
|
|
14877
15543
|
).map(([date, messages]) => /* @__PURE__ */ jsxs("div", { className: "mb-2 flex flex-col", children: [
|
|
14878
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
15544
|
+
/* @__PURE__ */ jsx("div", { className: "sticky top-1.5 z-20 mb-2 flex justify-center py-1", children: /* @__PURE__ */ jsx(
|
|
15545
|
+
ChatDateJumpMenu,
|
|
15546
|
+
{
|
|
15547
|
+
label: date,
|
|
15548
|
+
minDay: jumpDateBounds.minDay,
|
|
15549
|
+
maxDay: jumpDateBounds.maxDay,
|
|
15550
|
+
onJump: handleJumpTo
|
|
15551
|
+
}
|
|
15552
|
+
) }),
|
|
14879
15553
|
messages.map((m, msgIndex) => {
|
|
14880
|
-
const senderLabel = typeof m.sender === "string" ? m.sender : "User";
|
|
14881
|
-
const senderImage = !m.isOwnMessage ? activeChannel?.isGroup ? void 0 : activeChannel?.image : void 0;
|
|
14882
15554
|
const isGroupChat = !!activeChannel?.isGroup;
|
|
15555
|
+
const participants = conversationInfo?.participants ?? [];
|
|
15556
|
+
const { name: senderLabel, image: groupSenderImage } = isGroupChat && !m.isOwnMessage ? resolveGroupSenderDisplay(m, allUsers, participants) : { name: typeof m.sender === "string" ? m.sender : "User", image: void 0 };
|
|
15557
|
+
const senderImage = !m.isOwnMessage ? isGroupChat ? groupSenderImage : activeChannel?.image : void 0;
|
|
14883
15558
|
const prevMessage = msgIndex > 0 ? messages[msgIndex - 1] : null;
|
|
14884
15559
|
const nextMessage = msgIndex < messages.length - 1 ? messages[msgIndex + 1] : null;
|
|
14885
15560
|
const isGroupedWithPrev = !!prevMessage && isSameMessageSide(prevMessage, m, isGroupChat);
|
|
@@ -14926,6 +15601,7 @@ var ActiveChannelMessagesView = (props) => {
|
|
|
14926
15601
|
conversationInfo,
|
|
14927
15602
|
isHighlighted: String(m._id || m.id) === String(searchedMessageId),
|
|
14928
15603
|
senderName: senderLabel,
|
|
15604
|
+
senderId: getMessageSenderId2(m),
|
|
14929
15605
|
senderImage,
|
|
14930
15606
|
showSenderName,
|
|
14931
15607
|
showSenderLabel,
|
|
@@ -14966,6 +15642,16 @@ var ActiveChannelMessagesView = (props) => {
|
|
|
14966
15642
|
onForward: handleBatchForward
|
|
14967
15643
|
}
|
|
14968
15644
|
),
|
|
15645
|
+
showScrollToBottom && !selectionMode && /* @__PURE__ */ jsx(
|
|
15646
|
+
"button",
|
|
15647
|
+
{
|
|
15648
|
+
type: "button",
|
|
15649
|
+
onClick: handleScrollToBottom,
|
|
15650
|
+
className: "chat-scroll-to-bottom",
|
|
15651
|
+
"aria-label": "Scroll to latest messages",
|
|
15652
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-5", strokeWidth: 2.25 })
|
|
15653
|
+
}
|
|
15654
|
+
),
|
|
14969
15655
|
isInitialLoading && /* @__PURE__ */ 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: [
|
|
14970
15656
|
/* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin text-(--chat-theme)" }),
|
|
14971
15657
|
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-bold uppercase tracking-[0.15em] text-(--chat-muted)", children: "Loading messages..." })
|
|
@@ -15589,10 +16275,10 @@ function useChannelMessageBox({
|
|
|
15589
16275
|
const composerDisabledReason = conversationId ? composerDisabledByConversation[conversationId] : void 0;
|
|
15590
16276
|
const fileInputRef = useRef(null);
|
|
15591
16277
|
const attachmentsCountRef = useRef(0);
|
|
15592
|
-
|
|
16278
|
+
React2__default.useEffect(() => {
|
|
15593
16279
|
attachmentsCountRef.current = state.attachments.length;
|
|
15594
16280
|
}, [state.attachments.length]);
|
|
15595
|
-
|
|
16281
|
+
React2__default.useEffect(() => {
|
|
15596
16282
|
const draft = {
|
|
15597
16283
|
messageInput: state.messageInput,
|
|
15598
16284
|
attachments: state.attachments
|
|
@@ -15600,7 +16286,7 @@ function useChannelMessageBox({
|
|
|
15600
16286
|
syncComposerRef(draft);
|
|
15601
16287
|
updateConversationDraft(conversationIdRef.current, draft);
|
|
15602
16288
|
}, [state.messageInput, state.attachments, syncComposerRef]);
|
|
15603
|
-
|
|
16289
|
+
React2__default.useEffect(() => {
|
|
15604
16290
|
if (typingTimeoutRef.current) {
|
|
15605
16291
|
clearTimeout(typingTimeoutRef.current);
|
|
15606
16292
|
typingTimeoutRef.current = null;
|
|
@@ -16151,10 +16837,10 @@ function useForwardModal({ isOpen, onClose, items, onForwardComplete }) {
|
|
|
16151
16837
|
targetChannelRef.current = channel;
|
|
16152
16838
|
const targetConversationIds = [String(channel.conversationId)];
|
|
16153
16839
|
items.forEach((item) => {
|
|
16154
|
-
const
|
|
16155
|
-
if (!
|
|
16840
|
+
const messageId2 = String(item.message._id || item.message.id || "");
|
|
16841
|
+
if (!messageId2) return;
|
|
16156
16842
|
const payload = {
|
|
16157
|
-
messageId,
|
|
16843
|
+
messageId: messageId2,
|
|
16158
16844
|
sender: String(loggedUserDetails._id),
|
|
16159
16845
|
sourceConversationId: item.message.conversationId ? String(item.message.conversationId) : void 0,
|
|
16160
16846
|
targetConversationIds,
|
|
@@ -16631,8 +17317,8 @@ var ChatMain = ({
|
|
|
16631
17317
|
viewportHeight = "full",
|
|
16632
17318
|
viewportClassName
|
|
16633
17319
|
}) => {
|
|
16634
|
-
const clientObj =
|
|
16635
|
-
const uiConfigObj =
|
|
17320
|
+
const clientObj = React2__default.useMemo(() => ({ id: clientId }), [clientId]);
|
|
17321
|
+
const uiConfigObj = React2__default.useMemo(
|
|
16636
17322
|
() => ({
|
|
16637
17323
|
...uiConfig || {},
|
|
16638
17324
|
components: { ...uiConfig?.components, ...components },
|
|
@@ -17067,6 +17753,6 @@ var packageDefaultComponents = {
|
|
|
17067
17753
|
// src/index.ts
|
|
17068
17754
|
var index_default = ChatMain_default;
|
|
17069
17755
|
|
|
17070
|
-
export { CHAT_API_KEYS, CHAT_GET_API_KEYS, Channel, ChannelHeaderView_default as ChannelHeader, ChannelListView_default as ChannelList, ChannelListItem_default as ChannelListItem, Chat, ChatAlertsProvider, ChatAvatar_default as ChatAvatar, ChatCustomizationProvider, ChatLayout_default as ChatLayout, ChatLocaleProvider, ChatMain_default as ChatMain, ChatThemeProvider, ChatViewport, DefaultChannelListItem, DefaultChatAvatar, DefaultChatLayout_default as DefaultChatLayout, ForwardModalView as ForwardModal, HeaderCallActions_default as HeaderCallActions, LoggedUserDetails_default as LoggedUserDetails, ChannelMessageBoxView_default as MessageInput, MessageItemView as MessageItem, ActiveChannelMessagesView_default as MessageList, capitalizeFirst, index_default as default, defaultChatClassNames, defaultChatComponents, defaultChatFeatures, defaultChatLayoutConfig, downloadFile, getChatBaseUrl, getChatQueryParamApis, getChatQueryParams, getChatQueryParamsByApi, getChatSocketUrl, getFirstAndLastNameOneCharacter, getResponsiveWidth, getSocketConfig, isEmpty, mergeChatCustomization, mergeChatLayoutConfig, packageDefaultComponents, resolveApiUrl, resolveChatApiKey, resolveSocketUrl, setChatAccessToken, setChatBaseURL, setChatClientId, setChatQueryParamApis, setChatQueryParams, setChatQueryParamsByApi, setChatSocketUrl, showNotification, socket_service_default as socketService, uniqueList, useChatAlerts, useChatContext, useChatController, useChatCustomization, useChatCustomizationOptional, useChatFeatures, useChatFeaturesOptional, useChatLocale, useStore as useChatStore, useChatTheme };
|
|
17756
|
+
export { CHAT_API_KEYS, CHAT_GET_API_KEYS, Calendar, CalendarDayButton, Channel, ChannelHeaderView_default as ChannelHeader, ChannelListView_default as ChannelList, ChannelListItem_default as ChannelListItem, Chat, ChatAlertsProvider, ChatAvatar_default as ChatAvatar, ChatCustomizationProvider, ChatDateJumpMenu, ChatLayout_default as ChatLayout, ChatLocaleProvider, ChatMain_default as ChatMain, ChatThemeProvider, ChatViewport, DefaultChannelListItem, DefaultChatAvatar, DefaultChatLayout_default as DefaultChatLayout, ForwardModalView as ForwardModal, HeaderCallActions_default as HeaderCallActions, LoggedUserDetails_default as LoggedUserDetails, ChannelMessageBoxView_default as MessageInput, MessageItemView as MessageItem, ActiveChannelMessagesView_default as MessageList, capitalizeFirst, clampJumpDate, index_default as default, defaultChatClassNames, defaultChatComponents, defaultChatFeatures, defaultChatLayoutConfig, downloadFile, getChatBaseUrl, getChatQueryParamApis, getChatQueryParams, getChatQueryParamsByApi, getChatSocketUrl, getFirstAndLastNameOneCharacter, getResponsiveWidth, getSocketConfig, isEmpty, mergeChatCustomization, mergeChatLayoutConfig, packageDefaultComponents, resolveApiUrl, resolveChatApiKey, resolveJumpDateBounds, resolveJumpPreset, resolveJumpStep, resolveSocketUrl, setChatAccessToken, setChatBaseURL, setChatClientId, setChatQueryParamApis, setChatQueryParams, setChatQueryParamsByApi, setChatSocketUrl, showNotification, smoothScrollToMessage, socket_service_default as socketService, startOfLocalDay, toDateInputValue, uniqueList, useChatAlerts, useChatContext, useChatController, useChatCustomization, useChatCustomizationOptional, useChatFeatures, useChatFeaturesOptional, useChatLocale, useStore as useChatStore, useChatTheme };
|
|
17071
17757
|
//# sourceMappingURL=index.mjs.map
|
|
17072
17758
|
//# sourceMappingURL=index.mjs.map
|