@pubuduth-aplicy/chat-ui 2.2.5 → 2.2.7
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
package/src/components/Chat.tsx
CHANGED
|
@@ -35,6 +35,22 @@ export const Chat = () => {
|
|
|
35
35
|
|
|
36
36
|
// Optional: update UI
|
|
37
37
|
updateMessageStatus(message._id, "delivered");
|
|
38
|
+
|
|
39
|
+
// Send read receipt if user is viewing this conversation
|
|
40
|
+
// This ensures messages are marked as "read" immediately when both users are in the same chat
|
|
41
|
+
if (message.conversationId === selectedConversation?._id) {
|
|
42
|
+
sendMessage({
|
|
43
|
+
event: "messageRead",
|
|
44
|
+
data: {
|
|
45
|
+
messageIds: [message._id],
|
|
46
|
+
chatId: message.conversationId,
|
|
47
|
+
senderId: message.senderId,
|
|
48
|
+
receiverId: message.receiverId,
|
|
49
|
+
receiverRole: message.receiverRole,
|
|
50
|
+
senderRole: message.senderRole,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
38
54
|
}
|
|
39
55
|
} catch (error) {
|
|
40
56
|
console.error("WebSocket message parse error:", error);
|
|
@@ -67,13 +67,13 @@ const Message = ({ message }: MessageProps) => {
|
|
|
67
67
|
|
|
68
68
|
const handleInProgress = () => {
|
|
69
69
|
console.log("Booking started (In Progress)");
|
|
70
|
-
window.location.href = `/booking/all`;
|
|
70
|
+
window.location.href = `/booking/all#${message.meta?.bookingDetails?.bookingId}`;
|
|
71
71
|
// Update booking status to InProgress
|
|
72
72
|
};
|
|
73
73
|
|
|
74
74
|
const handleComplete = () => {
|
|
75
75
|
console.log("Booking completed!");
|
|
76
|
-
window.location.href = `/booking/all`;
|
|
76
|
+
window.location.href = `/booking/all#${message.meta?.bookingDetails?.bookingId}`;
|
|
77
77
|
// Update booking status to Completed
|
|
78
78
|
};
|
|
79
79
|
|
|
@@ -83,7 +83,7 @@ const Message = ({ message }: MessageProps) => {
|
|
|
83
83
|
window.location.href = `/customer/customer-reviews`;
|
|
84
84
|
} else if (role === "provider") {
|
|
85
85
|
console.log("Navigate to review page for provider → customer");
|
|
86
|
-
window.location.href = `/booking/all`;
|
|
86
|
+
window.location.href = `/booking/all#${message.meta?.bookingDetails?.bookingId}`;
|
|
87
87
|
}
|
|
88
88
|
};
|
|
89
89
|
|
|
@@ -546,7 +546,18 @@ const Message = ({ message }: MessageProps) => {
|
|
|
546
546
|
};
|
|
547
547
|
|
|
548
548
|
const formatLastMessageTime = (dateString: string) => {
|
|
549
|
+
// Validate date input
|
|
550
|
+
if (!dateString) {
|
|
551
|
+
return "";
|
|
552
|
+
}
|
|
553
|
+
|
|
549
554
|
const date = new Date(dateString);
|
|
555
|
+
|
|
556
|
+
// Check if date is valid
|
|
557
|
+
if (isNaN(date.getTime())) {
|
|
558
|
+
return "";
|
|
559
|
+
}
|
|
560
|
+
|
|
550
561
|
const now = new Date();
|
|
551
562
|
|
|
552
563
|
const isToday = date.toDateString() === now.toDateString();
|
|
@@ -79,7 +79,18 @@ const Conversation = ({ conversation }: ConversationProps) => {
|
|
|
79
79
|
: participant?.name || "Conversation";
|
|
80
80
|
|
|
81
81
|
const formatLastMessageTime = (dateString: string) => {
|
|
82
|
+
// Validate date input
|
|
83
|
+
if (!dateString) {
|
|
84
|
+
return "";
|
|
85
|
+
}
|
|
86
|
+
|
|
82
87
|
const date = new Date(dateString);
|
|
88
|
+
|
|
89
|
+
// Check if date is valid
|
|
90
|
+
if (isNaN(date.getTime())) {
|
|
91
|
+
return "";
|
|
92
|
+
}
|
|
93
|
+
|
|
83
94
|
const now = new Date();
|
|
84
95
|
|
|
85
96
|
const isToday = date.toDateString() === now.toDateString();
|
|
@@ -130,8 +141,8 @@ const Conversation = ({ conversation }: ConversationProps) => {
|
|
|
130
141
|
<img
|
|
131
142
|
className="w-10 h-10 rounded-full"
|
|
132
143
|
src={
|
|
133
|
-
participant?.
|
|
134
|
-
? participant?.
|
|
144
|
+
participant?.profilePic
|
|
145
|
+
? participant?.profilePic
|
|
135
146
|
: defaultProfilePicture
|
|
136
147
|
}
|
|
137
148
|
alt="User Avatar"
|
|
@@ -134,7 +134,18 @@ const Conversations = () => {
|
|
|
134
134
|
};
|
|
135
135
|
|
|
136
136
|
const handleNewMessage = (newMessage: any) => {
|
|
137
|
-
|
|
137
|
+
// Logic to handle inconsistent message structure
|
|
138
|
+
const conversationId = newMessage?.conversationId || newMessage?.chatId;
|
|
139
|
+
|
|
140
|
+
if (!conversationId) return;
|
|
141
|
+
|
|
142
|
+
// Ensure we have a valid message object
|
|
143
|
+
const messageData = {
|
|
144
|
+
...newMessage,
|
|
145
|
+
conversationId: conversationId, // Normalize to conversationId
|
|
146
|
+
createdAt: newMessage.createdAt || new Date().toISOString(),
|
|
147
|
+
updatedAt: newMessage.updatedAt || new Date().toISOString()
|
|
148
|
+
};
|
|
138
149
|
|
|
139
150
|
setConversations((prev) => {
|
|
140
151
|
const personalChats = [...prev.personalChats];
|
|
@@ -142,20 +153,20 @@ const Conversations = () => {
|
|
|
142
153
|
|
|
143
154
|
const updateConversation = (convo: ConversationType) => ({
|
|
144
155
|
...convo,
|
|
145
|
-
lastMessage:
|
|
156
|
+
lastMessage: messageData,
|
|
146
157
|
updatedAt: new Date().toISOString(),
|
|
147
158
|
unreadMessageIds:
|
|
148
|
-
userId !==
|
|
149
|
-
? [...(convo.unreadMessageIds || []),
|
|
159
|
+
userId !== messageData.senderId
|
|
160
|
+
? [...(convo.unreadMessageIds || []), messageData._id]
|
|
150
161
|
: convo.unreadMessageIds || [],
|
|
151
162
|
unreadMessageCount:
|
|
152
|
-
userId !==
|
|
163
|
+
userId !== messageData.senderId
|
|
153
164
|
? (convo.unreadMessageCount || 0) + 1
|
|
154
165
|
: convo.unreadMessageCount || 0,
|
|
155
166
|
});
|
|
156
167
|
|
|
157
168
|
const personalIndex = personalChats.findIndex(
|
|
158
|
-
(c) => c._id ===
|
|
169
|
+
(c) => c._id === conversationId
|
|
159
170
|
);
|
|
160
171
|
if (personalIndex >= 0) {
|
|
161
172
|
personalChats[personalIndex] = updateConversation(
|
|
@@ -167,7 +178,7 @@ const Conversations = () => {
|
|
|
167
178
|
for (const serviceId in groupedServiceChats) {
|
|
168
179
|
const serviceIndex = groupedServiceChats[
|
|
169
180
|
serviceId
|
|
170
|
-
].conversations.findIndex((c) => c._id ===
|
|
181
|
+
].conversations.findIndex((c) => c._id === conversationId);
|
|
171
182
|
if (serviceIndex >= 0) {
|
|
172
183
|
const updatedConversations = [
|
|
173
184
|
...groupedServiceChats[serviceId].conversations,
|
|
@@ -183,10 +194,14 @@ const Conversations = () => {
|
|
|
183
194
|
}
|
|
184
195
|
}
|
|
185
196
|
|
|
197
|
+
// Only add new conversation if we have enough info
|
|
198
|
+
// This part usually requires fetching full conversation details if it doesn't exist
|
|
199
|
+
// For now we just skip if not found to avoid ghost chats
|
|
200
|
+
/*
|
|
186
201
|
personalChats.push({
|
|
187
|
-
_id:
|
|
202
|
+
_id: conversationId,
|
|
188
203
|
participants: [newMessage.senderId, newMessage.receiverId],
|
|
189
|
-
lastMessage:
|
|
204
|
+
lastMessage: messageData,
|
|
190
205
|
updatedAt: new Date().toISOString(),
|
|
191
206
|
unreadMessageIds:
|
|
192
207
|
userId !== newMessage.senderId ? [newMessage._id] : [],
|
|
@@ -194,7 +209,9 @@ const Conversations = () => {
|
|
|
194
209
|
type: "personal",
|
|
195
210
|
readReceipts: [],
|
|
196
211
|
createdAt: new Date().toISOString(),
|
|
212
|
+
participantDetails: [] // Missing details
|
|
197
213
|
});
|
|
214
|
+
*/
|
|
198
215
|
|
|
199
216
|
return { personalChats, groupedServiceChats };
|
|
200
217
|
});
|
|
@@ -204,6 +221,7 @@ const Conversations = () => {
|
|
|
204
221
|
try {
|
|
205
222
|
const data = JSON.parse(event.data);
|
|
206
223
|
if (data.event === "newMessage") {
|
|
224
|
+
// data.data is the message object
|
|
207
225
|
handleNewMessage(data.data);
|
|
208
226
|
} else if (
|
|
209
227
|
data.event === "messageStatusUpdated" &&
|
|
@@ -275,8 +293,8 @@ const Conversations = () => {
|
|
|
275
293
|
);
|
|
276
294
|
|
|
277
295
|
const serviceUnreadCount = Object.values(conversations.groupedServiceChats)
|
|
278
|
-
.flatMap((group) => group.conversations)
|
|
279
|
-
.reduce((total, convo) => total + (convo.unreadMessageCount || 0), 0);
|
|
296
|
+
.flatMap((group: any) => group.conversations)
|
|
297
|
+
.reduce((total: any, convo: any) => total + (convo.unreadMessageCount || 0), 0);
|
|
280
298
|
|
|
281
299
|
return (
|
|
282
300
|
<div className="chatSidebarConversations">
|
package/src/stores/Zustant.ts
CHANGED
package/src/types/type.ts
CHANGED
|
@@ -6,16 +6,19 @@ export interface ChatWindowProps {
|
|
|
6
6
|
export interface ParticipantDetails {
|
|
7
7
|
_id: string;
|
|
8
8
|
username: string;
|
|
9
|
-
password
|
|
10
|
-
acctype
|
|
11
|
-
contactno
|
|
12
|
-
country
|
|
13
|
-
email
|
|
14
|
-
verified
|
|
15
|
-
profilePic
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
password?: string;
|
|
10
|
+
acctype?: string;
|
|
11
|
+
contactno?: string;
|
|
12
|
+
country?: string;
|
|
13
|
+
email?: string;
|
|
14
|
+
verified?: string;
|
|
15
|
+
profilePic?: string;
|
|
16
|
+
firstname?: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
idpic?: string;
|
|
19
|
+
createdAt?: string;
|
|
20
|
+
updatedAt?: string;
|
|
21
|
+
__v?: number;
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
export interface Conversation {
|
|
@@ -32,14 +35,15 @@ export interface Conversation {
|
|
|
32
35
|
createdAt: string;
|
|
33
36
|
updatedAt: string;
|
|
34
37
|
__v: number;
|
|
38
|
+
conversationId?: string;
|
|
35
39
|
};
|
|
36
40
|
updatedAt: string;
|
|
37
41
|
__v: number;
|
|
38
|
-
participantDetails: ParticipantDetails;
|
|
42
|
+
participantDetails: ParticipantDetails[];
|
|
39
43
|
participants?: string[];
|
|
40
44
|
// readReceipts?: string[] | [];
|
|
41
45
|
unreadMessageIds: string[];
|
|
42
|
-
type?:
|
|
46
|
+
type?: 'personal' | 'service' | undefined;
|
|
43
47
|
bookingId?: string;
|
|
44
48
|
serviceId?: string;
|
|
45
49
|
unreadMessageCount?: number
|