@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pubuduth-aplicy/chat-ui",
3
- "version": "2.2.5",
3
+ "version": "2.2.7",
4
4
  "description": "This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.",
5
5
  "license": "ISC",
6
6
  "author": "",
@@ -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?.profilePicture
134
- ? participant?.profilePicture
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
- if (!newMessage?.conversationId) return;
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: newMessage,
156
+ lastMessage: messageData,
146
157
  updatedAt: new Date().toISOString(),
147
158
  unreadMessageIds:
148
- userId !== newMessage.senderId
149
- ? [...(convo.unreadMessageIds || []), newMessage._id]
159
+ userId !== messageData.senderId
160
+ ? [...(convo.unreadMessageIds || []), messageData._id]
150
161
  : convo.unreadMessageIds || [],
151
162
  unreadMessageCount:
152
- userId !== newMessage.senderId
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 === newMessage.conversationId
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 === newMessage.conversationId);
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: newMessage.conversationId,
202
+ _id: conversationId,
188
203
  participants: [newMessage.senderId, newMessage.receiverId],
189
- lastMessage: newMessage,
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">
@@ -11,7 +11,7 @@ interface ChatUIState {
11
11
  profilePic: string;
12
12
  firstname: string;
13
13
  idpic: string;
14
- };
14
+ } | any; // Allow array or object until fully refactored
15
15
  unreadMessageIds?: string[];
16
16
  _id: string;
17
17
  type?: 'personal' | 'service';
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: string;
10
- acctype: string;
11
- contactno: string;
12
- country: string;
13
- email: string;
14
- verified: string;
15
- profilePic: string;
16
- createdAt: string;
17
- updatedAt: string;
18
- __v: number;
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?: string | undefined;
46
+ type?: 'personal' | 'service' | undefined;
43
47
  bookingId?: string;
44
48
  serviceId?: string;
45
49
  unreadMessageCount?: number