@pubuduth-aplicy/chat-ui 2.1.70 → 2.1.73
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 +1 -1
- package/src/components/Chat.tsx +30 -17
- package/src/components/messages/Message.tsx +275 -172
- package/src/components/messages/MessageContainer.tsx +89 -52
- package/src/components/messages/MessageInput.tsx +12 -10
- package/src/components/messages/Messages.tsx +46 -24
- package/src/components/sidebar/Conversation.tsx +147 -64
- package/src/components/sidebar/Conversations.tsx +6 -1
- package/src/providers/ChatProvider.tsx +46 -26
- package/src/stores/Zustant.ts +19 -17
- package/src/style/style.css +110 -24
- package/src/types/type.ts +6 -4
|
@@ -11,58 +11,97 @@ const MessageContainer = () => {
|
|
|
11
11
|
setSelectedConversation,
|
|
12
12
|
onlineUsers,
|
|
13
13
|
setOnlineUsers,
|
|
14
|
+
setMessages,
|
|
14
15
|
} = useChatUIStore();
|
|
15
|
-
const { socket, sendMessage } = useChatContext();
|
|
16
|
-
const {role}= getChatConfig()
|
|
16
|
+
const { socket, sendMessage, isUserOnline } = useChatContext();
|
|
17
|
+
const { role } = getChatConfig();
|
|
17
18
|
const [joinedChats, setJoinedChats] = useState<Set<string>>(new Set());
|
|
18
19
|
|
|
20
|
+
// useEffect(() => {
|
|
21
|
+
// if (!socket) return;
|
|
22
|
+
|
|
23
|
+
// const handleMessage = (event) => {
|
|
24
|
+
// try {
|
|
25
|
+
// const parsed = JSON.parse(event.data);
|
|
26
|
+
|
|
27
|
+
// if (parsed.event === 'newMessage') {
|
|
28
|
+
// const message = parsed.data;
|
|
29
|
+
// console.log('Received message:', message);
|
|
30
|
+
|
|
31
|
+
// if (selectedConversation?._id !== message.chatId) return;
|
|
32
|
+
|
|
33
|
+
// const messageId = message._id || message.messageId;
|
|
34
|
+
// console.log('Message ID for unread:', messageId);
|
|
35
|
+
|
|
36
|
+
// if (!messageId) {
|
|
37
|
+
// console.warn('Message has no _id or messageId, skipping unread tracking');
|
|
38
|
+
// return;
|
|
39
|
+
// }
|
|
40
|
+
|
|
41
|
+
// const updatedUnread = [
|
|
42
|
+
// ...(selectedConversation?.unreadMessageIds || []),
|
|
43
|
+
// messageId,
|
|
44
|
+
// ];
|
|
45
|
+
|
|
46
|
+
// console.log('Updated unreadMessageIds:', updatedUnread);
|
|
47
|
+
|
|
48
|
+
// setSelectedConversation({
|
|
49
|
+
// ...selectedConversation,
|
|
50
|
+
// unreadMessageIds: updatedUnread,
|
|
51
|
+
// });
|
|
52
|
+
// }
|
|
53
|
+
|
|
54
|
+
// // Handle other events...
|
|
55
|
+
|
|
56
|
+
// } catch (error) {
|
|
57
|
+
// console.error("WebSocket message parse error:", error);
|
|
58
|
+
// }
|
|
59
|
+
// };
|
|
60
|
+
|
|
61
|
+
// socket.addEventListener("message", handleMessage);
|
|
62
|
+
// return () => socket.removeEventListener("message", handleMessage);
|
|
63
|
+
// }, [socket, setMessages, selectedConversation, setSelectedConversation]);
|
|
64
|
+
|
|
19
65
|
// Join chat room when conversation is selected
|
|
66
|
+
|
|
20
67
|
useEffect(() => {
|
|
21
68
|
if (selectedConversation?._id && socket?.readyState === WebSocket.OPEN) {
|
|
22
69
|
const chatId = selectedConversation._id;
|
|
23
|
-
|
|
70
|
+
const unreadMessages = selectedConversation.unreadMessageIds || [];
|
|
71
|
+
|
|
72
|
+
console.log("Unread messages:", unreadMessages);
|
|
73
|
+
|
|
74
|
+
if (unreadMessages.length > 0) {
|
|
24
75
|
sendMessage({
|
|
25
|
-
|
|
26
|
-
|
|
76
|
+
event: "messageRead",
|
|
77
|
+
data: {
|
|
78
|
+
messageIds: unreadMessages,
|
|
79
|
+
chatId: chatId,
|
|
80
|
+
},
|
|
27
81
|
});
|
|
28
|
-
setJoinedChats(new Set(joinedChats).add(chatId));
|
|
29
82
|
}
|
|
83
|
+
// }
|
|
30
84
|
}
|
|
31
|
-
}, [
|
|
85
|
+
}, [
|
|
86
|
+
selectedConversation?._id,
|
|
87
|
+
socket,
|
|
88
|
+
selectedConversation?.unreadMessageIds,
|
|
89
|
+
sendMessage,
|
|
90
|
+
joinedChats,
|
|
91
|
+
]);
|
|
32
92
|
|
|
33
93
|
// Listen for online users updates
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
if (!socket) return;
|
|
36
|
-
|
|
37
|
-
const handleMessage = (event: MessageEvent) => {
|
|
38
|
-
try {
|
|
39
|
-
const data = JSON.parse(event.data);
|
|
40
|
-
if (data.type === "getOnlineUsers") {
|
|
41
|
-
setOnlineUsers(data.users);
|
|
42
|
-
}
|
|
43
|
-
} catch (error) {
|
|
44
|
-
console.error("Error parsing message:", error);
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
94
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return () => {
|
|
51
|
-
socket.removeEventListener("message", handleMessage);
|
|
52
|
-
};
|
|
53
|
-
}, [socket, setOnlineUsers]);
|
|
54
|
-
|
|
55
|
-
role === 'admin' && Array.isArray(selectedConversation?.participantDetails)
|
|
95
|
+
role === "admin" && Array.isArray(selectedConversation?.participantDetails)
|
|
56
96
|
? selectedConversation.participantDetails[1]?.profilePic
|
|
57
97
|
: !Array.isArray(selectedConversation?.participantDetails)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const isUserOnline =
|
|
62
|
-
!Array.isArray(selectedConversation?.participantDetails) &&
|
|
63
|
-
!!selectedConversation?.participantDetails?._id &&
|
|
64
|
-
onlineUsers?.includes(selectedConversation.participantDetails._id);
|
|
98
|
+
? selectedConversation?.participantDetails?.profilePic
|
|
99
|
+
: undefined;
|
|
65
100
|
|
|
101
|
+
const isOnline =
|
|
102
|
+
!Array.isArray(selectedConversation?.participantDetails) &&
|
|
103
|
+
!!selectedConversation?.participantDetails?._id &&
|
|
104
|
+
isUserOnline(selectedConversation.participantDetails._id);
|
|
66
105
|
|
|
67
106
|
// Cleanup on unmount
|
|
68
107
|
useEffect(() => {
|
|
@@ -84,34 +123,32 @@ const MessageContainer = () => {
|
|
|
84
123
|
className="chatMessageContainerInnerImg"
|
|
85
124
|
alt="Profile"
|
|
86
125
|
src={
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
126
|
+
role === "admin" &&
|
|
127
|
+
Array.isArray(selectedConversation?.participantDetails)
|
|
128
|
+
? selectedConversation.participantDetails[1]?.profilePic
|
|
129
|
+
: !Array.isArray(selectedConversation?.participantDetails)
|
|
130
|
+
? selectedConversation?.participantDetails?.profilePic
|
|
131
|
+
: undefined
|
|
92
132
|
}
|
|
93
133
|
/>
|
|
94
134
|
<div className="chatMessageContainerOutter">
|
|
95
135
|
<div className="chatMessageContainerOutterDiv">
|
|
96
136
|
<p className="chatMessageContainerOutterDiv_name">
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
</p>
|
|
104
|
-
<p className="text-sm">
|
|
105
|
-
{isUserOnline ? "Online" : "Offline"}
|
|
137
|
+
{role === "admin" &&
|
|
138
|
+
Array.isArray(selectedConversation?.participantDetails)
|
|
139
|
+
? selectedConversation.participantDetails[1]?.firstname
|
|
140
|
+
: !Array.isArray(selectedConversation?.participantDetails)
|
|
141
|
+
? selectedConversation?.participantDetails?.firstname
|
|
142
|
+
: undefined}
|
|
106
143
|
</p>
|
|
144
|
+
<p className="text-sm">{isOnline ? "Online" : "Offline"}</p>
|
|
107
145
|
</div>
|
|
108
146
|
</div>
|
|
109
147
|
</div>
|
|
110
148
|
</div>
|
|
111
149
|
|
|
112
150
|
<Messages />
|
|
113
|
-
{role !==
|
|
114
|
-
|
|
151
|
+
{role !== "admin" && <MessageInput />}
|
|
115
152
|
</>
|
|
116
153
|
)}
|
|
117
154
|
</div>
|
|
@@ -213,4 +250,4 @@ const EmptyInbox: React.FC<EmptyInboxProps> = ({
|
|
|
213
250
|
<p className="text-gray-500 max-w-sm">{description}</p>
|
|
214
251
|
</div>
|
|
215
252
|
);
|
|
216
|
-
};
|
|
253
|
+
};
|
|
@@ -227,7 +227,7 @@ const MessageInput = () => {
|
|
|
227
227
|
text: message1,
|
|
228
228
|
message: message1,
|
|
229
229
|
senderId: userId,
|
|
230
|
-
status: "
|
|
230
|
+
status: "pending" as MessageStatus,
|
|
231
231
|
createdAt: new Date().toISOString(),
|
|
232
232
|
media: attachmentsRef.current.map((att) => ({
|
|
233
233
|
type: att.type,
|
|
@@ -321,15 +321,17 @@ const MessageInput = () => {
|
|
|
321
321
|
|
|
322
322
|
// Send message via WebSocket
|
|
323
323
|
sendMessage({
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
324
|
+
event: "sendMessage",
|
|
325
|
+
data: {
|
|
326
|
+
chatId: selectedConversation?._id,
|
|
327
|
+
message: message1,
|
|
328
|
+
messageId: data[1]._id,
|
|
329
|
+
attachments: successfulUploads,
|
|
330
|
+
senderId: userId,
|
|
331
|
+
receiverId:
|
|
332
|
+
!Array.isArray(selectedConversation?.participantDetails) &&
|
|
333
|
+
selectedConversation?.participantDetails._id,
|
|
334
|
+
},
|
|
333
335
|
});
|
|
334
336
|
},
|
|
335
337
|
onError: (error) => {
|
|
@@ -42,12 +42,12 @@ const Messages = () => {
|
|
|
42
42
|
|
|
43
43
|
const handleMessage = (event: MessageEvent) => {
|
|
44
44
|
try {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
const newMessage =
|
|
45
|
+
const parsed = JSON.parse(event.data);
|
|
46
|
+
console.log("Parsed WebSocket message1:", parsed);
|
|
47
|
+
if (parsed.type === "newMessage" || parsed.event === "newMessage") {
|
|
48
|
+
const newMessage = parsed.message;
|
|
49
49
|
newMessage.shouldShake = true;
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
setMessages((prevMessages) => {
|
|
52
52
|
const isDuplicate = prevMessages.some(
|
|
53
53
|
(msg) =>
|
|
@@ -61,11 +61,28 @@ const Messages = () => {
|
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
const statusOrder = ["sent", "delivered", "read"];
|
|
65
|
+
if (parsed.event === "messageStatusUpdated") {
|
|
66
|
+
const { messageId, status } = parsed.data || {};
|
|
67
|
+
if (!messageId) {
|
|
68
|
+
console.error("Missing messageId in status update", parsed);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log(`Updating status for ${messageId} to ${status}`);
|
|
65
73
|
setMessages((prev) =>
|
|
66
|
-
prev.map((msg) =>
|
|
67
|
-
msg._id
|
|
68
|
-
|
|
74
|
+
prev.map((msg) => {
|
|
75
|
+
if (msg._id !== messageId) return msg;
|
|
76
|
+
|
|
77
|
+
// Only update if new status is higher than current status
|
|
78
|
+
const currentIdx = statusOrder.indexOf(msg.status);
|
|
79
|
+
const newIdx = statusOrder.indexOf(status);
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
...msg,
|
|
83
|
+
status: newIdx > currentIdx ? status : msg.status,
|
|
84
|
+
};
|
|
85
|
+
})
|
|
69
86
|
);
|
|
70
87
|
}
|
|
71
88
|
} catch (error) {
|
|
@@ -80,11 +97,29 @@ const Messages = () => {
|
|
|
80
97
|
};
|
|
81
98
|
}, [socket, selectedConversation?._id, setMessages, userId]);
|
|
82
99
|
|
|
100
|
+
const sendDeliveryConfirmation = (messageId: string) => {
|
|
101
|
+
if (!socket) return;
|
|
102
|
+
|
|
103
|
+
const message = {
|
|
104
|
+
event: "confirmDelivery",
|
|
105
|
+
data: {
|
|
106
|
+
messageId,
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
// timestamp: Date.now()
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
socket.send(JSON.stringify(message));
|
|
113
|
+
};
|
|
114
|
+
|
|
83
115
|
// Scroll to bottom when messages change
|
|
84
116
|
useEffect(() => {
|
|
85
117
|
if (messages.length > 0) {
|
|
86
118
|
setTimeout(() => {
|
|
87
|
-
lastMessageRef.current?.scrollIntoView({
|
|
119
|
+
lastMessageRef.current?.scrollIntoView({
|
|
120
|
+
behavior: "smooth",
|
|
121
|
+
block: "end",
|
|
122
|
+
});
|
|
88
123
|
}, 100);
|
|
89
124
|
}
|
|
90
125
|
}, [messages.length]);
|
|
@@ -113,19 +148,6 @@ const Messages = () => {
|
|
|
113
148
|
return () => observer.disconnect();
|
|
114
149
|
}, [messages, socket]);
|
|
115
150
|
|
|
116
|
-
|
|
117
|
-
const sendDeliveryConfirmation = (messageId: string) => {
|
|
118
|
-
if (!socket) return;
|
|
119
|
-
|
|
120
|
-
const message = {
|
|
121
|
-
type: "confirmDelivery",
|
|
122
|
-
messageId,
|
|
123
|
-
// timestamp: Date.now()
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
socket.send(JSON.stringify(message));
|
|
127
|
-
};
|
|
128
|
-
|
|
129
151
|
return (
|
|
130
152
|
<div
|
|
131
153
|
className="chatMessages"
|
|
@@ -157,4 +179,4 @@ const Messages = () => {
|
|
|
157
179
|
);
|
|
158
180
|
};
|
|
159
181
|
|
|
160
|
-
export default Messages;
|
|
182
|
+
export default Messages;
|
|
@@ -1,59 +1,112 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
2
|
import { useChatContext } from "../../providers/ChatProvider";
|
|
3
3
|
import useChatUIStore from "../../stores/Zustant";
|
|
4
4
|
import { ConversationProps } from "../../types/type";
|
|
5
5
|
import { getChatConfig } from "@pubuduth-aplicy/chat-ui";
|
|
6
6
|
|
|
7
7
|
const Conversation = ({ conversation }: ConversationProps) => {
|
|
8
|
-
const {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const {
|
|
9
|
+
setSelectedConversation,
|
|
10
|
+
setOnlineUsers,
|
|
11
|
+
onlineUsers,
|
|
12
|
+
setMessages,
|
|
13
|
+
selectedConversation,
|
|
14
|
+
updateMessageStatus,
|
|
15
|
+
} = useChatUIStore();
|
|
16
|
+
const { socket, sendMessage, isUserOnline } = useChatContext();
|
|
17
|
+
const { role } = getChatConfig();
|
|
18
|
+
// const handleSelectConversation = async () => {
|
|
19
|
+
// setSelectedConversation(conversation);
|
|
20
|
+
|
|
21
|
+
// // Mark unread messages as read
|
|
22
|
+
// const unreadMessages = conversation.unreadMessageIds || [];
|
|
23
|
+
// if (selectedConversation?._id && socket?.readyState === WebSocket.OPEN) {
|
|
24
|
+
// sendMessage({
|
|
25
|
+
// event: "joinChat",
|
|
26
|
+
// data: {
|
|
27
|
+
// chatId: conversation._id,
|
|
28
|
+
// },
|
|
29
|
+
// // event: "messageRead",
|
|
30
|
+
// // data: {
|
|
31
|
+
// // messageIds: unreadMessages,
|
|
32
|
+
// // chatId: conversation._id,
|
|
33
|
+
// // },
|
|
34
|
+
// });
|
|
35
|
+
// }
|
|
36
|
+
// };
|
|
37
|
+
|
|
38
|
+
const [activeChatId, setActiveChatId] = useState(null);
|
|
39
|
+
|
|
12
40
|
const handleSelectConversation = async () => {
|
|
41
|
+
// Set as selected conversation
|
|
13
42
|
setSelectedConversation(conversation);
|
|
14
43
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
44
|
+
// Mark as active chat
|
|
45
|
+
setActiveChatId(conversation._id);
|
|
46
|
+
|
|
47
|
+
// Join chat via WebSocket
|
|
48
|
+
if (socket?.readyState === WebSocket.OPEN) {
|
|
19
49
|
sendMessage({
|
|
20
|
-
event: "
|
|
21
|
-
data:{
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
50
|
+
event: "joinChat",
|
|
51
|
+
data: {
|
|
52
|
+
chatId: conversation._id,
|
|
53
|
+
// Send any existing unread messages to mark as read
|
|
54
|
+
messageIds: conversation.unreadMessageIds || [],
|
|
55
|
+
},
|
|
26
56
|
});
|
|
27
57
|
}
|
|
28
58
|
};
|
|
29
59
|
|
|
30
|
-
//
|
|
60
|
+
// // Enhanced message handler
|
|
31
61
|
useEffect(() => {
|
|
32
62
|
if (!socket) return;
|
|
33
63
|
|
|
34
64
|
const handleMessage = (event: MessageEvent) => {
|
|
35
65
|
try {
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
66
|
+
const message = JSON.parse(event.data);
|
|
67
|
+
console.log("fdgfd", message);
|
|
68
|
+
|
|
69
|
+
if (message.event === "newMessage") {
|
|
70
|
+
const newMessage = message.data;
|
|
71
|
+
|
|
72
|
+
// If this is the active chat, mark as read immediately
|
|
73
|
+
if (activeChatId === newMessage.conversationId) {
|
|
74
|
+
console.log("rtrtr");
|
|
75
|
+
|
|
76
|
+
sendMessage({
|
|
77
|
+
event: "messageRead",
|
|
78
|
+
data: {
|
|
79
|
+
messageIds: [newMessage._id],
|
|
80
|
+
chatId: newMessage.conversationId,
|
|
81
|
+
senderId: newMessage.senderId,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Optimistic UI update
|
|
86
|
+
// updateMessageStatus(newMessage._id, "read");
|
|
87
|
+
} else {
|
|
88
|
+
// Otherwise mark as delivered
|
|
89
|
+
sendMessage({
|
|
90
|
+
event: "confirmDelivery",
|
|
91
|
+
data: {
|
|
92
|
+
messageIds: [newMessage._id],
|
|
93
|
+
chatId: newMessage.conversationId,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
}
|
|
39
97
|
}
|
|
40
98
|
} catch (error) {
|
|
41
|
-
console.error("Error
|
|
99
|
+
console.error("Error handling message:", error);
|
|
42
100
|
}
|
|
43
101
|
};
|
|
44
102
|
|
|
45
103
|
socket.addEventListener("message", handleMessage);
|
|
104
|
+
return () => socket.removeEventListener("message", handleMessage);
|
|
105
|
+
}, [socket, activeChatId, setMessages, updateMessageStatus]);
|
|
46
106
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}, [socket, setOnlineUsers]);
|
|
51
|
-
|
|
52
|
-
const isUserOnline =
|
|
53
|
-
conversation?.participantDetails?._id &&
|
|
54
|
-
onlineUsers?.includes(conversation.participantDetails._id);
|
|
55
|
-
|
|
56
|
-
const isSelected = selectedConversation?._id === conversation._id;
|
|
107
|
+
const isOnline = isUserOnline(conversation?.participantDetails?._id || "");
|
|
108
|
+
console.log("Online status:", isOnline);
|
|
109
|
+
const isSelected = selectedConversation?._id === conversation._id;
|
|
57
110
|
|
|
58
111
|
return (
|
|
59
112
|
<>
|
|
@@ -65,54 +118,84 @@ const Conversation = ({ conversation }: ConversationProps) => {
|
|
|
65
118
|
<img
|
|
66
119
|
className="conversation-img"
|
|
67
120
|
src={
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
121
|
+
role === "admin" &&
|
|
122
|
+
Array.isArray(conversation?.participantDetails)
|
|
123
|
+
? conversation.participantDetails[1]?.profilePic
|
|
124
|
+
: !Array.isArray(conversation?.participantDetails)
|
|
125
|
+
? conversation?.participantDetails?.profilePic
|
|
126
|
+
: undefined
|
|
73
127
|
}
|
|
74
|
-
|
|
75
128
|
alt="User Avatar"
|
|
76
129
|
/>
|
|
77
130
|
<span
|
|
78
|
-
className={`chatSidebarStatusDot ${
|
|
79
|
-
isUserOnline && "online"
|
|
80
|
-
}`}
|
|
131
|
+
className={`chatSidebarStatusDot ${isOnline && "online"}`}
|
|
81
132
|
></span>
|
|
82
133
|
</div>
|
|
83
134
|
|
|
84
135
|
<div className="conversation-info">
|
|
85
136
|
<div className="conversation-header">
|
|
86
137
|
<p className="conversation-name">
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
138
|
+
{role === "admin" &&
|
|
139
|
+
Array.isArray(conversation?.participantDetails)
|
|
140
|
+
? conversation.participantDetails[1]?.firstname
|
|
141
|
+
: !Array.isArray(conversation?.participantDetails)
|
|
142
|
+
? conversation?.participantDetails?.firstname
|
|
143
|
+
: undefined}
|
|
94
144
|
</p>
|
|
95
145
|
<span className="conversation-time">
|
|
96
|
-
{
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
146
|
+
{conversation.lastMessage.status === "deleted"
|
|
147
|
+
? // Show deleted timestamp if message is deleted
|
|
148
|
+
new Date(
|
|
149
|
+
conversation.lastMessage.updatedAt
|
|
150
|
+
).toLocaleTimeString([], {
|
|
151
|
+
hour: "2-digit",
|
|
152
|
+
minute: "2-digit",
|
|
153
|
+
})
|
|
154
|
+
: conversation.lastMessage.status === "edited"
|
|
155
|
+
? // Show updated timestamp if message was edited
|
|
156
|
+
new Date(
|
|
157
|
+
conversation.lastMessage.updatedAt
|
|
158
|
+
).toLocaleTimeString([], {
|
|
159
|
+
hour: "2-digit",
|
|
160
|
+
minute: "2-digit",
|
|
161
|
+
})
|
|
162
|
+
: // Default to created timestamp
|
|
163
|
+
new Date(
|
|
164
|
+
conversation.lastMessage.createdAt
|
|
165
|
+
).toLocaleTimeString([], {
|
|
166
|
+
hour: "2-digit",
|
|
167
|
+
minute: "2-digit",
|
|
168
|
+
})}
|
|
103
169
|
</span>
|
|
104
170
|
</div>
|
|
105
171
|
<p className="conversation-message">
|
|
106
|
-
{conversation.lastMessage.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
172
|
+
{conversation.lastMessage.status === "deleted" ? (
|
|
173
|
+
"This message was deleted"
|
|
174
|
+
) : conversation.lastMessage.type !== "system" &&
|
|
175
|
+
conversation.lastMessage.message.length > 50 ? (
|
|
176
|
+
conversation.lastMessage.message.slice(0, 50) + "..."
|
|
177
|
+
) : conversation.lastMessage.media.length > 0 ? (
|
|
178
|
+
<div
|
|
179
|
+
style={{ display: "flex", alignItems: "center", gap: "5px" }}
|
|
180
|
+
>
|
|
181
|
+
<svg
|
|
182
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
183
|
+
width="18"
|
|
184
|
+
height="18"
|
|
185
|
+
viewBox="0 0 24 24"
|
|
186
|
+
fill="none"
|
|
187
|
+
stroke="currentColor"
|
|
188
|
+
strokeWidth="2"
|
|
189
|
+
strokeLinecap="round"
|
|
190
|
+
strokeLinejoin="round"
|
|
191
|
+
>
|
|
192
|
+
<path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"></path>
|
|
193
|
+
</svg>
|
|
194
|
+
attachment
|
|
195
|
+
</div>
|
|
196
|
+
) : (
|
|
197
|
+
conversation.lastMessage.message
|
|
198
|
+
)}
|
|
116
199
|
</p>
|
|
117
200
|
</div>
|
|
118
201
|
</div>
|
|
@@ -120,4 +203,4 @@ const Conversation = ({ conversation }: ConversationProps) => {
|
|
|
120
203
|
);
|
|
121
204
|
};
|
|
122
205
|
|
|
123
|
-
export default Conversation;
|
|
206
|
+
export default Conversation;
|
|
@@ -12,7 +12,12 @@ const Conversations = () => {
|
|
|
12
12
|
// const { loading, conversations } = useGetConversations();
|
|
13
13
|
return (
|
|
14
14
|
<div className="chatSidebarConversations">
|
|
15
|
-
<h2
|
|
15
|
+
<h2
|
|
16
|
+
className="text-lg font-semibold text-gray-700"
|
|
17
|
+
style={{ paddingLeft: "1rem" }}
|
|
18
|
+
>
|
|
19
|
+
All Messages
|
|
20
|
+
</h2>
|
|
16
21
|
{(!conversations || conversations.length === 0) && (
|
|
17
22
|
<div className="flex flex-col items-center justify-center p-8 text-center">
|
|
18
23
|
<div className="flex h-16 w-16 items-center justify-center rounded-full bg-gray-100 mb-4">
|