Untitled

 avatar
unknown
plain_text
2 years ago
3.8 kB
5
Indexable
import React, { useEffect, useRef, useState } from 'react';
import firebase from 'firebase/app';
import { useCollectionData } from 'react-firebase-hooks/firestore';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPaperPlane } from '@fortawesome/free-solid-svg-icons';
import ChatMessage from './ChatMessage';
import 'firebase/storage';

function ChatRoom() {
  const auth = firebase.auth();
  const firestore = firebase.firestore();
  const database = firebase.database();

  const dummy = useRef();
  const messagesRef = firestore.collection('messages');
  const query = messagesRef.orderBy('createdAt');
  const [messages] = useCollectionData(query, { idField: 'id' });
  const [formValue, setFormValue] = useState('');
  const [isSending, setIsSending] = useState(false);
  const [username, setUsername] = useState(null);
  const [selectedFile, setSelectedFile] = useState(null);

  const scrollToBottom = () => {
    dummy.current?.scrollIntoView({ behavior: 'smooth' });
  };

  useEffect(() => {
    let isMounted = true;
    scrollToBottom();
    const fetchUsername = async () => {
      const uid = auth.currentUser.uid;
      const usernameRef = database.ref(`users/${uid}/username`);
      const usernameSnapshot = await usernameRef.once('value');
      let username = usernameSnapshot.val();
      if (!username) {
        const user = auth.currentUser;
        username = user.displayName || user.email;
        usernameRef.set(username);
      }
      if (isMounted) {
        setUsername(username);
      }
    };

    if (auth.currentUser) {
      fetchUsername();
    }
    return () => {
      isMounted = false;
    };
  }, [auth, database]);

  const [cooldown, setCooldown] = useState(false);

  const handleSendMessage = async (e) => {
    e.preventDefault();
  
    if (cooldown) {
      return;
    }
  
    setCooldown(true);
    setIsSending(true);
  
    const { uid, photoURL, displayName, email } = auth.currentUser;
  
    if (selectedFile) {
      const storageRef = firebase.storage().ref();
      const fileRef = storageRef.child(selectedFile.name);
      await fileRef.put(selectedFile);
      const fileUrl = await fileRef.getDownloadURL();
      await messagesRef.add({
        fileUrl,
        createdAt: firebase.firestore.FieldValue.serverTimestamp(),
        uid,
        photoURL,
        username,
        displayName,
        email,
      });
    } else {
      await messagesRef.add({
        text: formValue,
        createdAt: firebase.firestore.FieldValue.serverTimestamp(),
        uid,
        photoURL,
        username,
        displayName,
        email,
      });
    }
  
    setFormValue('');
    setSelectedFile(null);
    scrollToBottom();
  
    setTimeout(() => {
      setIsSending(false);
      setCooldown(false);
    }, 3000);
  };  

  return (
    <>
      <main>
        {messages &&
          messages.map((msg, index, pool) => {
            const prev = pool[index - 1];
            const next = pool[index + 1];
            return (
              <ChatMessage
                key={msg.id}
                message={msg}
                id={msg.id}
                neighbour={{ prev, next }}
              />
            );
          })}
        <span ref={dummy}></span>
      </main>

      <form onSubmit={handleSendMessage}>
        <input
          value={formValue}
          onChange={(e) => setFormValue(e.target.value)}
          placeholder="Type a message"
        />
        <input type="file" onChange={(e) => setSelectedFile(e.target.files[0])} />
        <button
          className="chat-message-button"
          type="submit"
          disabled={!formValue || isSending}
        >
          <FontAwesomeIcon icon={faPaperPlane} />
        </button>
      </form>
    </>
  );
}

export default ChatRoom;
Editor is loading...