[chat] 유저별 메세지 구분하기

miin·2022년 5월 15일
0

Skill Collection [Function]

목록 보기
30/44

결과

full code

https://github.com/suminllll/chatting-sample

내용

  • 채팅방에 들어가면 전에 대화했던 내용이 그대로 불러와짐
  • 이전내용 중에 내가 친 메세지들은 오른쪽에 표시
  • 채팅을 치면 내가 보낸 메세지는 오른쪽으로 출력

코드

client

const { user } = useGuard(); //현재 유저, 사용자 토큰이 있는지 확인후 user 정보를 보내줌
const [messages, setMessages] = useState([]); //처음 렌더링시 이전 메세지들을 모두 담음
const [messages, setMessages] = useState([]); //처음에 이전 메세지들을 모두 담음

  //해당 방의 모든 이전 메세지 불러오기
  useEffect(() => {
    new Promise(async (res, rej) => {
      const url = `/rooms/chat/${props.roomNo}/message`;
      const result = await httpRequest("GET", url);
      const data = result.data;

      //data의 member_no와 현재 member_no가 같으면 isMyMessage로 추가함 
      // isMyMessage는 className으로 오른쪽에 붙여지는 ui
      if (result.success) {
        data.map((data) => {
          if (data.member_no === user?.member_no) {
            data.isMyMessage = true;
            return data;
          } else {
            return data;
          }
        });
        setMessages(data);
      }
    });
  }, [user]);

 //서버에서 채팅내용 받기
      socket.on("/rooms/message", (data) => {
        console.log(
          "서버에서 채팅내용 받기",
          data.data,
          data.data.memberNo,
          user?.member_no
        );

        //isMyMessage: 메세지를 입력한 member_no와 받아온 데이터의 memberNo가 같고,
        //data type이 USER_TEXT 이면 true를 반환, 현재 유저라는 의미
        //isMyMessage면 className을 변경하는 방법
        const notice = {
          ...data.data,
          isMyMessage:
            data.data.memberNo === user?.member_no &&
            data.data?.type === "USER_TEXT",
        };

        setMessages((messages) => [...messages, notice]);
      });

  //채팅 입력하면 message state에 저장
  const handleMessage = (e) => {
    e.preventDefault();
    setMessage(e.target.value);
  };

  //send가 실행되고 채팅 내용이 db로 추가됨
  const handleSend = () => {
    if (message) {
      if (message.length === 0) {
        alert("채팅 내용을 입력해주세요.");
        return;
      }

      //메세지 서버로 보냄
      socket.emit("/rooms/message", {
        chat: message,
        roomNo: props.roomNo,
        memberNo: user?.member_no,
        nick: user?.nick,
        type: "USER_TEXT",
      });

      setIsTyping(false);
      setMessage("");
    }
  };

return(
  <>
   <div key={key} className="chat_otherMsg">
        <div className={isMyMessage ? "myMsg" : "otherMsg"}>
          <div className="imgBox">
            <img alt="profileImg" src="/img/profile.jpeg" />
          </div>
          <div style={{ flex: 1 }} />
          <ul className="chat_chatWrap">
            <div className="chat_chatBox">
              <li className={isMyMessage ? "chat_my_profileName" : "profileName"}>
                {nick}
              </li>
              <li className="time">{time}</li>
            </div>
            <li className="chat_chatList">{chat}</li>
          </ul>
        </div>
      </div>

          <div className="chatInputWrap">
          <input
            className="chatInput"
            placeholder="Write a message.."
            onChange={handleMessage}
            onKeyUp={handleEnterOnMessage}
            value={message}
          />
          <button className="sendButton" onClick={handleSend}>
            Send
          </button>
        </div>
</>
)

server

  socket.on("/rooms/message", (data) => {
    console.log("채팅받음", data);

    const { roomNo, memberNo, chat } = data;
    _db
      .qry(
        `INSERT INTO chat(member_no, room_no, chat, sended) VALUES (:memberNo, :roomNo, :chat, now())`,
        data
      )
      .then(() => {
        io.in(roomNo).emit("/rooms/message", { data });
      });
  });

0개의 댓글