Chat Logic - abhiram-shaji/Langroove GitHub Wiki

1. useChat Hook

Function:
This custom hook manages chat functionality, including sending and receiving messages between users.

Example:

const { message, setMessage, messages, sendMessage } = useChat(recipientId);

This allows you to access the current message, set a new message, retrieve messages, and send messages in a component.


2. State Management with useState

Function:
This hook manages the state for the current message being typed and the list of messages.

Example:

const [message, setMessage] = useState('');
const [messages, setMessages] = useState<Message[]>([]);

Here, message starts as an empty string, and messages starts as an empty array.


3. Getting Current User

Function:
This retrieves the currently logged-in user using Firebase Authentication.

Example:

const currentUser = auth.currentUser; // Get the current user

This gets the current user object, which is used to manage chat interactions.


4. useEffect for Fetching Messages

Function:
This hook fetches messages from Firestore when the component mounts or when the recipient ID changes.

Example:

useEffect(() => {
  if (!currentUser || !recipientId) return;

  const chatId = [currentUser.uid, recipientId].sort().join('_');
  const chatRef = collection(db, 'chats', chatId, 'messages');
  const q = query(chatRef, orderBy('createdAt'));

  const unsubscribe = onSnapshot(q, (snapshot) => {
    const fetchedMessages = snapshot.docs.map((doc) => {
      const data = doc.data();
      return {
        id: doc.id,
        text: data.text,
        sender: data.sender === currentUser.uid ? 'me' : 'other',
      };
    }) as Message[];
    setMessages(fetchedMessages);
  });

  return unsubscribe; // Clean up listener on unmount
}, [currentUser, recipientId]);

When the user or recipient ID is set, it fetches messages and listens for real-time updates.


5. Sending Messages

Function:
This function handles sending a message to the recipient.

Example:

const sendMessage = async () => {
  if (!message.trim() || !currentUser) return;

  try {
    const chatId = [currentUser.uid, recipientId].sort().join('_');
    const chatRef = collection(db, 'chats', chatId, 'messages');

    await addDoc(chatRef, {
      text: message,
      sender: currentUser.uid,
      recipient: recipientId,
      createdAt: new Date(),
    });

    const chatMetaRef = doc(db, 'chats', chatId);
    await setDoc(chatMetaRef, {
      participants: [currentUser.uid, recipientId],
      lastMessage: { text: message, sender: currentUser.uid },
      lastMessageTimestamp: new Date(),
      unreadCount: 0,
    }, { merge: true });

    setMessage(''); // Clear the message input
  } catch (error) {
    console.error('Error sending message: ', error);
  }
};

This function checks if the message is valid, sends it to Firestore, and updates the chat metadata.


6. Returning Values

Function:
This hook returns the necessary values for the component using it.

Example:

return { message, setMessage, messages, sendMessage };

This allows the component to access the current message, the function to send a message, and the list of messages.


⚠️ **GitHub.com Fallback** ⚠️