mr-chat-bird 1.0.0 → 1.0.2

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.
Files changed (40) hide show
  1. package/package.json +41 -21
  2. package/app/layout.tsx +0 -69
  3. package/app/page.tsx +0 -9
  4. package/eslint.config.mjs +0 -11
  5. package/index.ts +0 -1
  6. package/next-env.d.ts +0 -5
  7. package/next.config.mjs +0 -30
  8. package/postcss.config.cjs +0 -14
  9. package/public/favicon.svg +0 -1
  10. package/src/components/ChatUserList/ChatUserList.module.css +0 -253
  11. package/src/components/ChatUserList/ChatUserList.tsx +0 -434
  12. package/src/components/ChatUserList/ChatUserList.type.tsx +0 -12
  13. package/src/components/ChatUserList/ChatUserMessage.tsx +0 -362
  14. package/src/components/ChatUserList/users_list.json +0 -648
  15. package/src/components/ColorSchemeToggle/ColorSchemeToggle.tsx +0 -15
  16. package/src/components/EmojiPickerPopover/EmojiPickerPopover.tsx +0 -72
  17. package/src/components/MrChat/index.tsx +0 -34
  18. package/src/components/RichTextEditor/DropzoneMenuItem.tsx +0 -33
  19. package/src/components/RichTextEditor/EmojiNode.tsx +0 -36
  20. package/src/components/RichTextEditor/RichTextEditor.module.css +0 -95
  21. package/src/components/RichTextEditor/RichTextEditor.tsx +0 -248
  22. package/src/components/UserProfile/UserProfileDrawer.module.css +0 -120
  23. package/src/components/UserProfile/UserProfileDrawer.tsx +0 -115
  24. package/src/components/VirtualizedList/ChatScrollContainer.tsx +0 -92
  25. package/src/components/VirtualizedList/index.tsx +0 -31
  26. package/src/lib/axios.ts +0 -12
  27. package/src/lib/socket.ts +0 -29
  28. package/src/store/provider.tsx +0 -8
  29. package/src/store/slices/ChatSlice.ts +0 -249
  30. package/src/store/socket/index.tsx +0 -32
  31. package/src/store/store.ts +0 -11
  32. package/src/theme.ts +0 -84
  33. package/src/utils/environment.ts +0 -5
  34. package/src/utils/helper.ts +0 -36
  35. package/src/utils/icons/richText/Add.svg +0 -1
  36. package/src/utils/icons/richText/AddReaction.svg +0 -1
  37. package/src/utils/icons/richText/Docs.svg +0 -1
  38. package/src/utils/icons/richText/Image.svg +0 -1
  39. package/src/utils/icons/richText/TextFormat.svg +0 -1
  40. package/tsconfig.json +0 -25
@@ -1,362 +0,0 @@
1
- "use client";
2
-
3
- import { Text, Menu, Avatar } from "@mantine/core";
4
- import {
5
- IconBan,
6
- IconDotsVertical,
7
- IconLock,
8
- IconTrash,
9
- } from "@tabler/icons-react";
10
- import CustomRichTextEditor from "../RichTextEditor/RichTextEditor";
11
- import classes from "./ChatUserList.module.css";
12
- import { getSocket } from "../../lib/socket";
13
- import { useDispatch, useSelector } from "react-redux";
14
- import { RootState } from "../../store/store";
15
- import { useEffect, useState } from "react";
16
- import {
17
- fetchMessagesByChatId,
18
- addNewMessage,
19
- addUserToChatList,
20
- deleteMessagesByChatId,
21
- } from "../../store/slices/ChatSlice";
22
- import DOMPurify from "dompurify";
23
- import { UserData } from "./ChatUserList.type";
24
- import { ChatScrollContainer } from "../VirtualizedList/ChatScrollContainer";
25
- import UserProfileDrawer from "../UserProfile/UserProfileDrawer";
26
-
27
- export function ChatUserMessage({
28
- chatId,
29
- enableChat,
30
- senderDetails,
31
- receiverDetails,
32
- onChatInitialized,
33
- }: {
34
- chatId?: string;
35
- enableChat?: boolean;
36
- senderDetails?: UserData;
37
- receiverDetails?: UserData;
38
- onChatInitialized?: (data: any) => void;
39
- }) {
40
- const dispatch = useDispatch<any>();
41
-
42
- const messageList: any = useSelector(
43
- (state: RootState) => state.chat.messageList,
44
- );
45
-
46
- const [page, setPage] = useState(0);
47
- const [scrollTrigger, setScrollTrigger] = useState(0);
48
- const [showUserInfo, setShowUserInfo] = useState(false);
49
-
50
- const messages = messageList?.rows?.data || [];
51
- const isEmpty = messages.length === 0;
52
-
53
- const loadOlderMessages = () => {
54
- const hasMore = messageList?.hasMore;
55
-
56
- if (!chatId || !hasMore) return;
57
- const nextPage = page + 1;
58
- dispatch(
59
- fetchMessagesByChatId({
60
- chatId,
61
- page: nextPage,
62
- userId: senderDetails?.userId,
63
- }),
64
- );
65
- setPage(nextPage);
66
- };
67
-
68
- useEffect(() => {
69
- if (chatId) {
70
- setPage(0);
71
- dispatch(
72
- fetchMessagesByChatId({
73
- chatId,
74
- page: 0,
75
- userId: senderDetails?.userId,
76
- }),
77
- );
78
- }
79
- }, [chatId]);
80
-
81
- useEffect(() => {
82
- if (!senderDetails?.userId) return;
83
- const socket = getSocket(senderDetails?.userId || "");
84
- if (!socket) return;
85
-
86
- const handleNewMessage = (data: any) => {
87
- if (data.chatId !== chatId) return;
88
-
89
- dispatch(
90
- addNewMessage({
91
- id: Date.now(),
92
- chatId: data.chatId,
93
- message: data.message,
94
- sender: data.sender,
95
- recipient: data.recipient,
96
- type: data.type,
97
- status: data.status,
98
- createdAt: data.time,
99
- }),
100
- );
101
- };
102
-
103
- socket.on("newmessage", handleNewMessage);
104
-
105
- return () => {
106
- socket.off("newmessage", handleNewMessage);
107
- };
108
- }, [chatId, senderDetails?.userId]);
109
-
110
- const handleSendMessage = (msg: string) => {
111
- const socket = getSocket(senderDetails?.userId || "");
112
-
113
- const payload = {
114
- message: msg,
115
- sender: senderDetails?.userId,
116
- receiver: receiverDetails?.userId,
117
- type: "text",
118
- };
119
-
120
- const isNewChat = !messageList?.rows?.data?.length;
121
-
122
- if (isNewChat) {
123
- socket?.emit(
124
- "initializeNewChat",
125
- {
126
- ...payload,
127
- senderUserDetails: {
128
- userId: senderDetails?.userId,
129
- username: senderDetails?.username,
130
- displayName: senderDetails?.displayName,
131
- avatar: senderDetails?.avatar,
132
- },
133
- receiverUserDetails: {
134
- userId: receiverDetails?.userId,
135
- username: receiverDetails?.username,
136
- displayName: receiverDetails?.displayName,
137
- avatar: receiverDetails?.avatar,
138
- },
139
- },
140
- (response: any) => {
141
- if (response?.status === "success") {
142
- const { data } = response;
143
- dispatch(
144
- addUserToChatList({
145
- id: Date.now(),
146
- chatId: data.chatId,
147
- message: data.message,
148
- sender: data.sender,
149
- recipient: data.recipient,
150
- type: data.type,
151
- status: data.status,
152
- createdAt: new Date(data.time).getTime(),
153
- updatedAt: new Date(data.time).getTime(),
154
- userId: receiverDetails?.userId,
155
- username: receiverDetails?.username,
156
- displayName: receiverDetails?.displayName,
157
- avatar: receiverDetails?.avatar,
158
- }),
159
- );
160
- dispatch(
161
- addNewMessage({
162
- id: Date.now(),
163
- chatId: data.chatId,
164
- message: data.message,
165
- sender: data.sender,
166
- recipient: data.recipient,
167
- type: data.type,
168
- status: data.status,
169
- createdAt: Date.now(),
170
- }),
171
- );
172
- onChatInitialized?.(data);
173
- } else {
174
- console.log("Failed to initialize chat", response?.error);
175
- }
176
- },
177
- );
178
- return;
179
- }
180
-
181
- socket?.emit("privatemessage", { ...payload, chatId: chatId });
182
- setScrollTrigger((prev) => prev + 1);
183
- };
184
-
185
- const handleLoadOlderMessages = () => {
186
- if (messageList.hasMore) {
187
- loadOlderMessages();
188
- }
189
- };
190
-
191
- const handleDeleteMessages = () => {
192
- if (!chatId || !senderDetails?.userId) return;
193
- dispatch(
194
- deleteMessagesByChatId({ chatId: chatId, userId: senderDetails?.userId }),
195
- );
196
- };
197
-
198
- return (
199
- <div className={classes.mainArea}>
200
- {/* Header */}
201
- <div className={classes.chatHeader}>
202
- {receiverDetails && (
203
- <>
204
- <div
205
- className={classes.receiverInfo}
206
- onClick={() => setShowUserInfo(true)}
207
- >
208
- {receiverDetails?.avatar ? (
209
- <Avatar src={receiverDetails.avatar} size={36} radius="xl" />
210
- ) : (
211
- <Avatar
212
- key={
213
- receiverDetails?.displayName || receiverDetails?.username
214
- }
215
- name={
216
- receiverDetails?.displayName || receiverDetails?.username
217
- }
218
- color="initials"
219
- />
220
- )}
221
-
222
- <Text fw={600} size="md">
223
- {receiverDetails?.displayName || receiverDetails?.username}
224
- </Text>
225
- </div>
226
-
227
- <Menu shadow="md" width={200} position="bottom-end">
228
- <Menu.Target>
229
- <IconDotsVertical size={20} style={{ cursor: "pointer" }} />
230
- </Menu.Target>
231
-
232
- <Menu.Dropdown>
233
- <Menu.Item
234
- color="red"
235
- leftSection={<IconTrash size={16} />}
236
- onClick={handleDeleteMessages}
237
- >
238
- Delete all messages
239
- </Menu.Item>
240
- <Menu.Item color="red" leftSection={<IconBan size={16} />}>
241
- Block
242
- </Menu.Item>
243
- </Menu.Dropdown>
244
- </Menu>
245
- </>
246
- )}
247
- </div>
248
-
249
- <div className={classes.messageArea}>
250
- {isEmpty ? (
251
- <div className={classes.emptyState}>
252
- <div className={classes.encryptionMinimal}>
253
- <IconLock size={20} stroke={1.8} />
254
- <Text className={classes.encryptionText} size="md">
255
- End-to-end encrypted
256
- </Text>
257
- </div>
258
- </div>
259
- ) : (
260
- <ChatScrollContainer
261
- data={messages}
262
- hasMore={messageList?.hasMore}
263
- loadMore={handleLoadOlderMessages}
264
- scrollToBottomTrigger={scrollTrigger}
265
- renderItem={(item: any, index: number) => {
266
- const isOutgoing = item?.sender === senderDetails?.userId;
267
-
268
- const currentDate = new Date(item?.createdAt);
269
- const prevItem = messages[index - 1];
270
-
271
- const showDate =
272
- index === 0 ||
273
- new Date(prevItem?.createdAt).toDateString() !==
274
- currentDate.toDateString();
275
-
276
- const today = new Date();
277
- const yesterday = new Date();
278
- yesterday.setDate(today.getDate() - 1);
279
-
280
- const isToday =
281
- currentDate.toDateString() === today.toDateString();
282
-
283
- const isYesterday =
284
- currentDate.toDateString() === yesterday.toDateString();
285
-
286
- let formattedDate = "";
287
-
288
- if (isToday) {
289
- formattedDate = "Today";
290
- } else if (isYesterday) {
291
- formattedDate = "Yesterday";
292
- } else {
293
- formattedDate = currentDate.toLocaleDateString(undefined, {
294
- weekday: "short",
295
- month: "short",
296
- day: "numeric",
297
- });
298
- }
299
-
300
- const time = currentDate.toLocaleTimeString([], {
301
- hour: "2-digit",
302
- minute: "2-digit",
303
- hour12: false,
304
- });
305
-
306
- return (
307
- <div key={item?.id + "_" + index}>
308
- {showDate && (
309
- <div className={classes.dateSeparator}>{formattedDate}</div>
310
- )}
311
-
312
- <div
313
- style={{
314
- borderRadius:
315
- item.sender === senderDetails?.userId
316
- ? "16px 16px 1px 16px"
317
- : "16px 16px 16px 1px",
318
- }}
319
- className={`${classes.messageBubble} ${
320
- isOutgoing ? classes.outgoing : classes.incoming
321
- }`}
322
- >
323
- <div
324
- className={classes.messageContent}
325
- dangerouslySetInnerHTML={{
326
- __html: DOMPurify.sanitize(item?.message),
327
- }}
328
- />
329
-
330
- <div className={classes.messageTime}>{time}</div>
331
- </div>
332
- </div>
333
- );
334
- }}
335
- />
336
- )}
337
- </div>
338
-
339
- {(chatId || enableChat) && (
340
- <div className={classes.inputBar}>
341
- <CustomRichTextEditor onSubmit={handleSendMessage} />
342
- </div>
343
- )}
344
-
345
- <UserProfileDrawer
346
- opened={showUserInfo}
347
- onClose={() => setShowUserInfo(false)}
348
- user={{
349
- avatar: receiverDetails?.avatar,
350
- username: receiverDetails?.username,
351
- displayName: receiverDetails?.displayName,
352
- }}
353
- onDeleteMessages={() => {
354
- handleDeleteMessages();
355
- }}
356
- onBlock={() => {
357
- console.log("block user");
358
- }}
359
- />
360
- </div>
361
- );
362
- }