@pubuduth-aplicy/chat-ui 2.1.94 → 2.1.96
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/package.json
CHANGED
|
@@ -6,9 +6,10 @@ const SystemNotice = () => (
|
|
|
6
6
|
margin: "1rem",
|
|
7
7
|
backgroundColor: "#f9f9f9",
|
|
8
8
|
fontSize: "14px",
|
|
9
|
+
textAlign: "center",
|
|
9
10
|
}}>
|
|
10
11
|
<strong style={{ display: "block", marginBottom: "0.5rem", textAlign:"center", fontSize:"smaller" }}>🛡 WE HAVE YOUR BACK</strong>
|
|
11
|
-
<p style={{fontSize:"x-small"}}>For added safety and your protection, keep payments and communications within Hirepanther.
|
|
12
|
+
<p style={{fontSize:"x-small", textAlign:"center"}}>For added safety and your protection, keep payments and communications within Hirepanther.
|
|
12
13
|
{/* <a href="#">Learn more</a> */}
|
|
13
14
|
</p>
|
|
14
15
|
</div>
|
|
@@ -29,9 +29,6 @@ const VirtualizedChatList = ({ conversations }: Props) => {
|
|
|
29
29
|
overflow: "auto",
|
|
30
30
|
}}
|
|
31
31
|
>
|
|
32
|
-
{/* {virtualizer.getVirtualItems().map((item) => {
|
|
33
|
-
const conversation = conversations[item.index];
|
|
34
|
-
return ( */}
|
|
35
32
|
<div
|
|
36
33
|
// key={item.key}
|
|
37
34
|
style={{
|
|
@@ -65,8 +62,6 @@ const VirtualizedChatList = ({ conversations }: Props) => {
|
|
|
65
62
|
);
|
|
66
63
|
})}
|
|
67
64
|
</div>
|
|
68
|
-
{/* ); */}
|
|
69
|
-
{/* })} */}
|
|
70
65
|
</div>
|
|
71
66
|
);
|
|
72
67
|
};
|
|
@@ -356,7 +356,7 @@ const Message = ({ message }: MessageProps) => {
|
|
|
356
356
|
<div className="circular-progress-container">
|
|
357
357
|
<div className="media-preview-background">
|
|
358
358
|
<img
|
|
359
|
-
src={`${
|
|
359
|
+
src={`${cdnUrl}${media.url}`}
|
|
360
360
|
alt={media.name}
|
|
361
361
|
className="blurred-preview"
|
|
362
362
|
/>
|
|
@@ -409,32 +409,13 @@ const Message = ({ message }: MessageProps) => {
|
|
|
409
409
|
}
|
|
410
410
|
/>
|
|
411
411
|
) : media.type === "video" ? (
|
|
412
|
-
|
|
413
|
-
<
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
>
|
|
419
|
-
<div className="file-icon video-icon">🎥</div>
|
|
420
|
-
|
|
421
|
-
<div className="file-info">
|
|
422
|
-
<span className="file-name">{media.name}</span>
|
|
423
|
-
<span className="file-size">
|
|
424
|
-
{(media.size / 1024 / 1024).toFixed(1)} MB
|
|
425
|
-
</span>
|
|
426
|
-
</div>
|
|
427
|
-
|
|
428
|
-
<div className="play-overlay">▶</div>
|
|
429
|
-
</div>
|
|
430
|
-
</>
|
|
412
|
+
<video controls className="media-content">
|
|
413
|
+
<source
|
|
414
|
+
src={`${cdnUrl}${media.url}`}
|
|
415
|
+
type={`video/${`${cdnUrl}${media.url}`.split(".").pop()}`}
|
|
416
|
+
/>
|
|
417
|
+
</video>
|
|
431
418
|
) : (
|
|
432
|
-
// <video controls className="media-content" preload="metadata">
|
|
433
|
-
// <source
|
|
434
|
-
// src={`${cdnUrl}${media.url}`}
|
|
435
|
-
// type={`video/${`${cdnUrl}${media.url}`.split(".").pop()?.toLocaleLowerCase()}`}
|
|
436
|
-
// />
|
|
437
|
-
// </video>
|
|
438
419
|
<div className="document-preview">
|
|
439
420
|
<div className="file-icon">
|
|
440
421
|
{media.type === "document" && "📄"}
|
|
@@ -455,7 +436,7 @@ const Message = ({ message }: MessageProps) => {
|
|
|
455
436
|
cancelDownload();
|
|
456
437
|
} else {
|
|
457
438
|
handleDownload(
|
|
458
|
-
`${cdnUrl}
|
|
439
|
+
`${cdnUrl}${media.url}`,
|
|
459
440
|
media.name,
|
|
460
441
|
index
|
|
461
442
|
);
|
|
@@ -34,54 +34,52 @@ const Conversations = () => {
|
|
|
34
34
|
}>({ personalChats: [], groupedServiceChats: {} });
|
|
35
35
|
|
|
36
36
|
// Process fetched data
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
allPersonalChats.push(group.personalConversation);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
group.serviceConversations.forEach((serviceGroup) => {
|
|
50
|
-
if (!allServiceChatsMap.has(serviceGroup.serviceId)) {
|
|
51
|
-
allServiceChatsMap.set(serviceGroup.serviceId, {
|
|
52
|
-
serviceTitle: serviceGroup.serviceTitle,
|
|
53
|
-
conversations: [],
|
|
54
|
-
});
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (!participantGroups) return;
|
|
39
|
+
const processConversations = (groups: ParticipantGroup[]) => {
|
|
40
|
+
const allPersonalChats: ConversationType[] = [];
|
|
41
|
+
const allServiceChatsMap = new Map<string, GroupedServiceChats[string]>();
|
|
42
|
+
|
|
43
|
+
groups.forEach((group) => {
|
|
44
|
+
if (group.personalConversation) {
|
|
45
|
+
allPersonalChats.push(group.personalConversation);
|
|
55
46
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
|
|
48
|
+
group.serviceConversations.forEach((serviceGroup) => {
|
|
49
|
+
if (!allServiceChatsMap.has(serviceGroup.serviceId)) {
|
|
50
|
+
allServiceChatsMap.set(serviceGroup.serviceId, {
|
|
51
|
+
serviceTitle: serviceGroup.serviceTitle,
|
|
52
|
+
conversations: [],
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const existing = allServiceChatsMap.get(serviceGroup.serviceId)!;
|
|
57
|
+
existing.conversations.push(...serviceGroup.conversations);
|
|
58
|
+
});
|
|
59
59
|
});
|
|
60
|
-
});
|
|
61
60
|
|
|
61
|
+
const sortConversations = (convos: ConversationType[]) =>
|
|
62
|
+
convos.sort(
|
|
63
|
+
(a, b) =>
|
|
64
|
+
new Date(b.lastMessage?.createdAt || b.updatedAt).getTime() -
|
|
65
|
+
new Date(a.lastMessage?.createdAt || a.updatedAt).getTime()
|
|
66
|
+
);
|
|
62
67
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
(
|
|
66
|
-
|
|
67
|
-
new Date(a.lastMessage?.createdAt || a.updatedAt).getTime()
|
|
68
|
-
);
|
|
68
|
+
sortConversations(allPersonalChats);
|
|
69
|
+
allServiceChatsMap.forEach((value) => {
|
|
70
|
+
sortConversations(value.conversations);
|
|
71
|
+
});
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
const result = {
|
|
74
|
+
personalChats: allPersonalChats,
|
|
75
|
+
groupedServiceChats: Object.fromEntries(allServiceChatsMap),
|
|
76
|
+
};
|
|
74
77
|
|
|
75
|
-
|
|
76
|
-
personalChats: allPersonalChats,
|
|
77
|
-
groupedServiceChats: Object.fromEntries(allServiceChatsMap),
|
|
78
|
+
return result;
|
|
78
79
|
};
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
setConversations(processConversations(participantGroups));
|
|
84
|
-
}, [participantGroups]);
|
|
81
|
+
setConversations(processConversations(participantGroups));
|
|
82
|
+
}, [participantGroups]);
|
|
85
83
|
|
|
86
84
|
// Real-time update listeners
|
|
87
85
|
useEffect(() => {
|
|
@@ -111,7 +109,9 @@ const Conversations = () => {
|
|
|
111
109
|
|
|
112
110
|
const personalIndex = personalChats.findIndex((c) => c._id === chatId);
|
|
113
111
|
if (personalIndex >= 0) {
|
|
114
|
-
personalChats[personalIndex] = updateRead(
|
|
112
|
+
personalChats[personalIndex] = updateRead(
|
|
113
|
+
personalChats[personalIndex]
|
|
114
|
+
);
|
|
115
115
|
return { personalChats, groupedServiceChats };
|
|
116
116
|
}
|
|
117
117
|
|
|
@@ -232,38 +232,41 @@ const Conversations = () => {
|
|
|
232
232
|
|
|
233
233
|
const lowerSearch = searchTerm?.toLowerCase().trim();
|
|
234
234
|
|
|
235
|
-
// Filter personal chats
|
|
236
|
-
const filteredPersonalChats = !lowerSearch
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
// Filter service chats
|
|
245
|
-
const filteredGroupedServiceChats: GroupedServiceChats = !lowerSearch
|
|
246
|
-
? conversations.groupedServiceChats
|
|
247
|
-
: Object.fromEntries(
|
|
248
|
-
Object.entries(conversations.groupedServiceChats)
|
|
249
|
-
.map(([serviceId, group]) => {
|
|
250
|
-
const filteredConvos = group.conversations.filter((convo) =>
|
|
251
|
-
convo.participantDetails?.some((p: any) =>
|
|
252
|
-
p?.name?.toLowerCase().includes(lowerSearch)
|
|
253
|
-
) ||
|
|
254
|
-
group.serviceTitle?.toLowerCase().includes(lowerSearch) ||
|
|
255
|
-
convo.serviceTitle?.toLowerCase().includes(lowerSearch)
|
|
256
|
-
);
|
|
257
|
-
return [serviceId, { ...group, conversations: filteredConvos }];
|
|
258
|
-
})
|
|
259
|
-
.filter(([_, group]) => group.conversations.length > 0)
|
|
260
|
-
);
|
|
235
|
+
// Filter personal chats
|
|
236
|
+
const filteredPersonalChats = !lowerSearch
|
|
237
|
+
? conversations.personalChats
|
|
238
|
+
: conversations.personalChats.filter((convo) =>
|
|
239
|
+
convo.participantDetails?.some((p: any) =>
|
|
240
|
+
p?.name?.toLowerCase().includes(lowerSearch)
|
|
241
|
+
)
|
|
242
|
+
);
|
|
261
243
|
|
|
262
|
-
//
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
244
|
+
// Filter service chats
|
|
245
|
+
const filteredGroupedServiceChats: GroupedServiceChats = !lowerSearch
|
|
246
|
+
? conversations.groupedServiceChats
|
|
247
|
+
: Object.fromEntries(
|
|
248
|
+
Object.entries(conversations.groupedServiceChats)
|
|
249
|
+
.map(([serviceId, group]) => {
|
|
250
|
+
const filteredConvos = group.conversations.filter(
|
|
251
|
+
(convo) =>
|
|
252
|
+
convo.participantDetails?.some((p: any) =>
|
|
253
|
+
p?.name?.toLowerCase().includes(lowerSearch)
|
|
254
|
+
) ||
|
|
255
|
+
group.serviceTitle?.toLowerCase().includes(lowerSearch) ||
|
|
256
|
+
convo.serviceTitle?.toLowerCase().includes(lowerSearch)
|
|
257
|
+
);
|
|
258
|
+
return [serviceId, { ...group, conversations: filteredConvos }];
|
|
259
|
+
})
|
|
260
|
+
.filter(([_, group]) => group.conversations.length > 0)
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
// Improved empty state logic
|
|
264
|
+
const showPersonalTab =
|
|
265
|
+
activeTab === "personal" && filteredPersonalChats.length > 0;
|
|
266
|
+
const showServiceTab =
|
|
267
|
+
activeTab === "service" &&
|
|
268
|
+
Object.keys(filteredGroupedServiceChats).length > 0;
|
|
269
|
+
const isEmpty = !showPersonalTab && !showServiceTab;
|
|
267
270
|
|
|
268
271
|
// Calculate unread counts for tabs
|
|
269
272
|
const personalUnreadCount = conversations.personalChats.reduce(
|
|
@@ -272,7 +275,7 @@ const isEmpty = !showPersonalTab && !showServiceTab;
|
|
|
272
275
|
);
|
|
273
276
|
|
|
274
277
|
const serviceUnreadCount = Object.values(conversations.groupedServiceChats)
|
|
275
|
-
.flatMap(group => group.conversations)
|
|
278
|
+
.flatMap((group) => group.conversations)
|
|
276
279
|
.reduce((total, convo) => total + (convo.unreadMessageCount || 0), 0);
|
|
277
280
|
|
|
278
281
|
return (
|
|
@@ -312,41 +315,43 @@ const isEmpty = !showPersonalTab && !showServiceTab;
|
|
|
312
315
|
</div>
|
|
313
316
|
|
|
314
317
|
{/* Tab Content */}
|
|
315
|
-
<div className="flex-1 overflow-auto">
|
|
318
|
+
<div className="flex-1 h-[550px] overflow-auto">
|
|
316
319
|
{isEmpty ? (
|
|
317
320
|
<div className="flex flex-col items-center justify-center p-8 text-center">
|
|
318
321
|
<h3 className="text-xl font-semibold mb-1">No Conversations</h3>
|
|
319
322
|
<p className="text-gray-500 text-sm mb-4">
|
|
320
|
-
{activeTab === "personal"
|
|
321
|
-
? "You have no personal messages yet."
|
|
323
|
+
{activeTab === "personal"
|
|
324
|
+
? "You have no personal messages yet."
|
|
322
325
|
: "You have no service messages yet."}
|
|
323
326
|
</p>
|
|
324
327
|
</div>
|
|
325
328
|
) : (
|
|
326
329
|
<>
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
330
|
+
<div className="h-full overflow-auto">
|
|
331
|
+
{activeTab === "personal" && filteredPersonalChats.length > 0 && (
|
|
332
|
+
<VirtualizedChatList conversations={filteredPersonalChats} />
|
|
333
|
+
)}
|
|
334
|
+
|
|
335
|
+
{activeTab === "service" &&
|
|
336
|
+
Object.entries(filteredGroupedServiceChats).length > 0 && (
|
|
337
|
+
<div className="p-2">
|
|
338
|
+
{Object.entries(filteredGroupedServiceChats).map(
|
|
339
|
+
([
|
|
340
|
+
serviceId,
|
|
341
|
+
{ serviceTitle, conversations: serviceConvos },
|
|
342
|
+
]) => (
|
|
343
|
+
<CollapsibleSection
|
|
344
|
+
key={serviceId}
|
|
345
|
+
title={serviceTitle}
|
|
346
|
+
defaultOpen={false}
|
|
347
|
+
>
|
|
348
|
+
<VirtualizedChatList conversations={serviceConvos} />
|
|
349
|
+
</CollapsibleSection>
|
|
350
|
+
)
|
|
351
|
+
)}
|
|
352
|
+
</div>
|
|
345
353
|
)}
|
|
346
|
-
|
|
347
|
-
)}
|
|
348
|
-
</div>
|
|
349
|
-
|
|
354
|
+
</div>
|
|
350
355
|
</>
|
|
351
356
|
)}
|
|
352
357
|
</div>
|
|
@@ -354,4 +359,4 @@ const isEmpty = !showPersonalTab && !showServiceTab;
|
|
|
354
359
|
);
|
|
355
360
|
};
|
|
356
361
|
|
|
357
|
-
export default Conversations;
|
|
362
|
+
export default Conversations;
|