@pubuduth-aplicy/chat-ui 2.1.41 → 2.1.43

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,12 +1,12 @@
1
1
  {
2
2
  "name": "@pubuduth-aplicy/chat-ui",
3
- "version": "2.1.41",
3
+ "version": "2.1.43",
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": "",
7
7
  "type": "module",
8
8
  "main": "src/index.tsx",
9
- "types": "dist/index.d.ts",
9
+ "types": "src/declarations.d.ts",
10
10
  "scripts": {
11
11
  "build": "tsc ",
12
12
  "prepare": "npm run build"
@@ -1,8 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { useCallback, useEffect, useRef, useState } from "react";
2
+ import { useEffect, useRef } from "react";
3
3
  import Message from "./Message";
4
4
  import { useChatContext } from "../../providers/ChatProvider";
5
- import { useMessages } from "../../hooks/queries/useChatApi";
6
5
  import useChatUIStore from "../../stores/Zustant";
7
6
  import { useInfiniteQuery } from "@tanstack/react-query";
8
7
  import { fetchMessages } from "../../service/messageService";
@@ -13,16 +12,11 @@ const Messages = () => {
13
12
  const { selectedConversation, setMessages, messages } = useChatUIStore();
14
13
  const { userId, socket } = useChatContext();
15
14
  const { ref, inView } = useInView();
16
- const scrollContainerRef = useRef<HTMLDivElement>(null);
17
- const [isInitialLoad, setIsInitialLoad] = useState(true);
18
- const [isAutoScrolling, setIsAutoScrolling] = useState(false);
19
- const [prevMessagesLength, setPrevMessagesLength] = useState(0);
20
- const loadingRef = useRef(false);
21
15
  // const { data, isLoading, isError, error } = useMessages(selectedConversation?._id, userId);
22
16
 
23
17
  const lastMessageRef = useRef<HTMLDivElement>(null);
24
18
 
25
- const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
19
+ const { data, fetchNextPage, isFetchingNextPage } =
26
20
  useInfiniteQuery({
27
21
  queryKey: ["messages", selectedConversation?._id, userId],
28
22
  queryFn: ({ pageParam = 1 }) =>
@@ -31,120 +25,8 @@ const Messages = () => {
31
25
  return lastPage.nextPage; // Use the nextPage from API response
32
26
  },
33
27
  initialPageParam: 1,
34
- });
28
+ })
35
29
 
36
- const [isLoadingMore, setIsLoadingMore] = useState(false);
37
- const scrollHeightBeforeLoad = useRef(0);
38
-
39
- const handleScroll = useCallback(() => {
40
- if (!scrollContainerRef.current || isFetchingNextPage || !hasNextPage) return;
41
-
42
- const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current;
43
-
44
- // Load more when scrolled near the top (100px threshold)
45
- if (scrollTop < 100) {
46
- // Save current scroll height before loading
47
- scrollHeightBeforeLoad.current = scrollHeight;
48
- setIsLoadingMore(true);
49
- fetchNextPage().finally(() => setIsLoadingMore(false));
50
- }
51
- }, [fetchNextPage, isFetchingNextPage, hasNextPage]);
52
-
53
- useEffect(() => {
54
- if (isLoadingMore && scrollContainerRef.current && scrollHeightBeforeLoad.current) {
55
- // After new messages are loaded, adjust scroll position to maintain the same view
56
- const container = scrollContainerRef.current;
57
- const newScrollHeight = container.scrollHeight;
58
- container.scrollTop = newScrollHeight - scrollHeightBeforeLoad.current;
59
- }
60
- }, [messages.length, isLoadingMore]);
61
-
62
- // Scroll to bottom for new messages
63
- useEffect(() => {
64
- if (messages.length > 0 && !isLoadingMore) {
65
- setTimeout(() => {
66
- lastMessageRef.current?.scrollIntoView({ behavior: "smooth" });
67
- }, 100);
68
- }
69
- }, [messages.length, isLoadingMore]);
70
-
71
-
72
- // const {
73
- // data,
74
- // fetchNextPage,
75
- // hasNextPage,
76
- // isFetchingNextPage,
77
- // isLoading,
78
- // } = useInfiniteQuery({
79
- // queryKey: ["messages", selectedConversation?._id, userId],
80
- // queryFn: ({ pageParam = 1 }) =>
81
- // fetchMessages(selectedConversation?._id, userId, pageParam),
82
- // getNextPageParam: (lastPage) => lastPage.nextPage ?? undefined,
83
- // onSuccess: (data) => {
84
- // const allMessages = data.pages.flatMap(page => page.messages);
85
- // setMessages(allMessages);
86
-
87
- // // Scroll to bottom on initial load
88
- // if (isInitialLoad && scrollContainerRef.current) {
89
- // setTimeout(() => {
90
- // scrollContainerRef.current?.scrollTo({
91
- // top: scrollContainerRef.current.scrollHeight,
92
- // behavior: 'auto'
93
- // });
94
- // setIsInitialLoad(false);
95
- // }, 100);
96
- // }
97
- // },
98
- // });
99
-
100
- // Maintain scroll position when loading older messages
101
-
102
-
103
- // useEffect(() => {
104
- // console.log('scrollContainerRef',scrollContainerRef.current);
105
-
106
- // if (!scrollContainerRef.current || isInitialLoad) return;
107
-
108
- // if (isFetchingNextPage) {
109
- // // Store current scroll position before loading
110
- // const container = scrollContainerRef.current;
111
- // const scrollTopBefore = container.scrollTop;
112
- // const scrollHeightBefore = container.scrollHeight;
113
- // console.log(container,'scrollHeightBefore',scrollHeightBefore,'container',scrollTopBefore);
114
-
115
- // loadingRef.current = true;
116
-
117
- // return () => {
118
- // // After messages are loaded, adjust scroll position
119
- // requestAnimationFrame(() => {
120
- // container.scrollTop = container.scrollHeight - scrollHeightBefore + scrollTopBefore;
121
- // loadingRef.current = false;
122
- // });
123
- // };
124
- // }
125
- // }, [isFetchingNextPage, isInitialLoad]);
126
-
127
- // Add this useEffect to handle new messages
128
- // useEffect(() => {
129
- // if (!scrollContainerRef.current || loadingRef.current) return;
130
-
131
- // const container = scrollContainerRef.current;
132
- // console.log("container",container);
133
-
134
- // const isNearBottom = container.scrollHeight - container.scrollTop - container.clientHeight < 100;
135
-
136
- // // Only auto-scroll if we're near bottom or it's a new message
137
- // if (isNearBottom || messages.length > prevMessagesLength) {
138
- // setIsAutoScrolling(true);
139
- // container.scrollTo({
140
- // top: container.scrollHeight,
141
- // behavior: messages.length > prevMessagesLength ? 'smooth' : 'auto'
142
- // });
143
- // setTimeout(() => setIsAutoScrolling(false), 500);
144
- // }
145
-
146
- // setPrevMessagesLength(messages.length);
147
- // }, [messages.length]);
148
30
 
149
31
  useEffect(() => {
150
32
  if (inView) {
@@ -152,13 +34,6 @@ const Messages = () => {
152
34
  }
153
35
  }, [fetchNextPage, inView]);
154
36
 
155
- // useEffect(() => {
156
- // if (data) {
157
- // console.log(data,'message data');
158
-
159
- // setMessages(data.messages);
160
- // }
161
- // }, [selectedConversation?._id, data]);
162
37
 
163
38
  useEffect(() => {
164
39
  if (data) {
@@ -173,20 +48,20 @@ useEffect(() => {
173
48
  useEffect(() => {
174
49
  if (!socket || !selectedConversation?._id) return;
175
50
 
176
- // const handleNewMessage = (newMessage: any) => {
177
- // newMessage.shouldShake = true;
178
- // console.log("📩 New message received:", newMessage);
179
- // setMessages((prevMessages) => [...prevMessages, newMessage[1]]);
180
- // };
51
+ const handleNewMessage = (newMessage: any) => {
52
+ newMessage.shouldShake = true;
53
+ console.log("📩 New message received:", newMessage);
54
+ setMessages((prevMessages) => [...prevMessages, newMessage[1]]);
55
+ };
181
56
 
182
- const handleNewMessage = (newMessage: any) => {
183
- newMessage.shouldShake = true;
184
- console.log("📩 New message received:", newMessage);
185
- setMessages((prevMessages) => {
186
- const updatedMessages = [...prevMessages, newMessage];
187
- return [...new Map(updatedMessages.map(m => [m._id, m])).values()]; // Prevent duplicates
188
- });
189
- };
57
+ // const handleNewMessage = (newMessage: any) => {
58
+ // newMessage.shouldShake = true;
59
+ // console.log("📩 New message received:", newMessage);
60
+ // setMessages((prevMessages) => {
61
+ // const updatedMessages = [...prevMessages, newMessage];
62
+ // return [...new Map(updatedMessages.map(m => [m._id, m])).values()]; // Prevent duplicates
63
+ // });
64
+ // };
190
65
 
191
66
 
192
67
  const handleStatusUpdate = ({
@@ -197,7 +72,7 @@ useEffect(() => {
197
72
  status: string;
198
73
  }) => {
199
74
  setMessages((prev) =>
200
- prev.map((msg) => (msg._id === messageId ? { ...msg, status } : msg))
75
+ prev.map((msg) => (msg.id === messageId ? { ...msg, status } : msg))
201
76
  );
202
77
  };
203
78
 
@@ -275,7 +150,7 @@ console.log("📩 Messages:", messages);
275
150
 
276
151
  return (
277
152
  <div className="chatMessages"
278
- ref={scrollContainerRef}
153
+
279
154
  style={{ overflowY: 'auto', height: '100%', position: 'relative' }}
280
155
  >
281
156
 
@@ -1,12 +1,13 @@
1
1
  // import { useSocketContext } from "../../context/SocketContext";
2
2
  // import useConversation from "../../zustand/useConversation";
3
3
 
4
+ import { useEffect } from "react";
4
5
  import { useChatContext } from "../../providers/ChatProvider";
5
6
  import useChatUIStore from "../../stores/Zustant";
6
7
  import { ConversationProps } from "../../types/type";
7
8
 
8
9
  const Conversation = ({ conversation, lastIdx }: ConversationProps) => {
9
- const { setSelectedConversation } = useChatUIStore();
10
+ const { setSelectedConversation, setOnlineUsers,onlineUsers } = useChatUIStore();
10
11
  const { socket } = useChatContext();
11
12
  console.log(conversation);
12
13
 
@@ -25,9 +26,22 @@ const handleSelectConversation = async () => {
25
26
  }
26
27
  };
27
28
 
28
- // const isSelected = selectedConversation?._id === conversation._id;
29
- // const { onlineUsers } = useSocketContext();
30
- // const isOnline = onlineUsers.includes(conversation._id);
29
+ useEffect(() => {
30
+ if (!socket) return;
31
+
32
+ const handleOnlineUsers = (users: string[]) => {
33
+ setOnlineUsers(users);
34
+ };
35
+
36
+ socket.on("getOnlineUsers", handleOnlineUsers);
37
+
38
+ return () => {
39
+ socket.off("getOnlineUsers", handleOnlineUsers);
40
+ };
41
+ }, [socket, setOnlineUsers]);
42
+
43
+ const isUserOnline = conversation?.participantDetails?._id &&
44
+ onlineUsers?.includes(conversation.participantDetails._id);
31
45
  return (
32
46
  <>
33
47
  <div
@@ -39,17 +53,22 @@ const handleSelectConversation = async () => {
39
53
  className="chatSidebarConversationImg"
40
54
  src={conversation.participantDetails?.profilePic|| conversation.participantDetails?.idpic}
41
55
  />
56
+ <p className="text-sm text-[#12bbb5]">
57
+ {isUserOnline ? "Online" : "Offline"}
58
+ </p>
42
59
  <div className="chatSidebarConversationContainer">
43
60
  {/* <div className="chatSidebarConversationInnerDiv"> */}
44
61
  <p className="text-sm text-gray-500">
45
62
  {conversation.participantDetails?.firstname}
46
63
  </p>
47
64
  <p className="chatSidebarConversationOuterDiv">
48
- Do you know which
65
+ {conversation.lastMessage.message}
49
66
  </p>
50
67
  {/* </div> */}
51
68
  </div>
52
- <span className="text-xs text-gray-500">08:12 AM</span>
69
+ <span className="text-xs text-gray-500">
70
+ {new Date(conversation.lastMessage.createdAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
71
+ </span>
53
72
  </div>
54
73
 
55
74
  {!lastIdx && <div className="divider my-0 py-0 h-1" />}
@@ -15,8 +15,19 @@ declare module '*.svg' {
15
15
  export default content;
16
16
  }
17
17
 
18
- declare module '@pubuduth-aplicy/chat-ui';
19
18
  declare module '@pubuduth-aplicy/chat-ui' {
20
- export function ChatUI(props: any): JSX.Element;
21
- // Define other exports and types as needed
22
- }
19
+ import { ReactNode, FC } from 'react';
20
+
21
+ interface ChatProviderProps {
22
+ userId: string;
23
+ children: ReactNode;
24
+ }
25
+
26
+ export const ChatProvider: FC<ChatProviderProps>;
27
+ export const Chat: FC;
28
+ export function useChatContext(): {
29
+ socket: any; // Replace 'any' with proper Socket type
30
+ userId: string;
31
+ onlineUsers: any[];
32
+ };
33
+ }