NodeJS+MongoDB

NodeJS+MongoDB Part3 - 채팅

hminor 2023. 6. 29. 13:14

/chat 으로 이동했을 때 페이지를 보여줄 수 있도록 하기

app.get("/chat", isLogin, (req, res) => {
    res.render("chat.ejs");
});

이후 chat.ejs 에서 로그인된 유저가 참여한 채팅 목록을 보여줄 수 있도록 data를 보내주기

app.get("/chat", isLogin, (req, res) => {
  console.log("req.user._id: ", req.user._id);
  db.collection("chatroom")
    .find({ member: ObjectID(req.user._id) })
    .toArray()
    .then((data) => {
      console.log(data);
      res.render("chat.ejs", { data: data });
    });
});

그리고 잠시 채팅방을 생성 시 바로 채팅 페이지로 갈 수 있게 하려면 아래와 같이 코드 작성하기

  • 헷갈렸던 부분이 채팅방을 개설 후 바로 redirect로 이동시켰지만 이동이 안되었는데
    • 확실하진 않지만
    • list.ejs 파일에서 post 요청 이후 done을 사용해서 location을 함께 바꿔주니까 이동이 되었다.
//server.js

app.post("/chat", isLogin, (req, res) => {
  const chatRoomData = {
    member: [ObjectID(req.user._id), ObjectID(req.body.user)],
    date: new Date(),
    title: req.body.title,
    nickname: [req.user.nickname, req.body.nickname],
  };
  db.collection("chatroom").findOne(
    { member: [ObjectID(req.user._id), ObjectID(req.body.user)] },
    (err, data) => {
      if (data === null) {
        db.collection("chatroom")
          .insertOne(chatRoomData)
          .then(() => {
            console.log("생성");
            res.redirect("/chat"); // /chat 페이지로 리다이렉션
          })
          .catch((error) => {
            console.log("에러:", error);
            res.redirect("/error"); // 실패 시 에러 페이지로 리다이렉션
          });
      } else {
        res.redirect("/chat"); // 이미 존재하는 경우에도 /chat 페이지로 리다이렉션
      }
    }
  );
});
<!doctype html>
<html>

<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"
    integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
  <link rel="stylesheet" href="/public/main.css">
  <title>NodeJS+MongoDB</title>
</head>

<body>
  <%- include('nav.html') %>

  <h2 class="my-3 text-center my-5">서버에서 가져온 할일 리스트</h2>

  <div class="container input-group mb-2">
    <input class="form-control" id="search_data">
    <button class="input-group-append btn btn-danger" id="search">검색</button>
  </div>

  <div class="container">

    <% for (var i=0; i< posts.length; i++) { %>
    <div class="card my-3 py-2" style="width: 100%;">
      <div class="card-body">
        <h5 class="card-title"><%= posts[i]._id %> </h5>
        <h6 class="card-subtitle mb-2 text-body-secondary">할일 제목: <%=  posts[i].제목 %> </h6>
        <p class="card-text">할일 마감날짜: <%= posts[i].날짜 %></p>
        <button class="detail rounded-sm" data-id="<%= posts[i]._id %>">상세</button>
        <button class="chat bg-success text-white rounded-sm" data-user="<%= posts[i].user %>"
          data-title="<%= posts[i].제목 %>" data-nickname="<%= posts[i].nickname %>">댓글</button>
        <button class="delete bg-danger text-white rounded-sm" data-id="<%= posts[i]._id %>">삭제</button>
      </div>
    </div>
    <% } %>
  </div>

  <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>

  <!-- chat -->
  <script>
    $('.chat').click((e) => {
      $.post('/chat', {
        user: e.target.dataset.user,
        title: e.target.dataset.title,
        nickname: e.target.dataset.nickname
      }).done(() => {
        location.href = '/chat'
      })
    })
  </script>
  <!-- search -->
  <script>
    $('#search').click((e) => {
      // window.location.replace('/search?이름=값')
      const search_data = $('#search_data').val()
      window.location.replace('/search?value=' + search_data)
    })
  </script>
  <!-- detail -->
  <script>
    $('.detail').click((e) => {
      location.href = '/detail/' + e.target.dataset.id
    })
  </script>
  <!-- delete -->
  <script>
    $('.delete').click((e) => {
      // e.target = 지금 클릭한 것, this = 지금 이벤트 동작하는 곳
      const id = e.target.dataset.id
      // var target = $(this)
      const target = $(e.target)
      // JQuery를 사용해서 AJAX 요청
      console.log(id);
      $.ajax({
        method: 'DELETE',
        url: '/delete',
        // 아래에서 _id의 값을 숫자 1로 전송을 해도 받아지는 데이터는 문자로 오게 된다.
        data: {
          _id: id
        },
      }).done((data) => {
        // 요청 성공시 아래 코드 실행
        console.log('성공');
        // 페이지를 새로고침하면서 데이터 갱신 시키기.
        // location.reload()
        // `지금 현재 타겟의 부모중 li태그를 찾아라`라는 의미이며 fadeOut()으로 서서히 사라지게 해달라는 메서드를 추가
        target.parent('div').parent('div').fadeOut()
      }).fail((xhr, textStatus, errorThrown) => {
        // xhr = xhr 안에 status, statusText, responseText 값들이 있어서 확인하면 됨, textStatus = 응답코드, errorThrown = 응답 메시지
        // 실패시 여기로 즉 400 에러가 발생시 여기 코드가 나옴.
      })
    })
  </script>

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous">
  </script>

</body>

</html>

 

그리고 클릭한 채팅방에 맞는 채팅 생성은 아래와 같다

//server.js

app.post("/msg", isLogin, (req, res) => {
  const saveMsg = {
    parent: req.body.parent,
    content: req.body.content,
    userId: req.user._id,
    date: new Date(),
  };

  db.collection("msg")
    .insertOne(saveMsg)
    .then((r) => {
      console.log("성공");
    });
});
<!doctype html>
<html>

<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <!-- Bootstrap CSS -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"
    integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
  <link rel="stylesheet" href="/public/main.css">


  <title>NodeJS+MongoDB</title>
  <style>
    .chat-content {
      height: 450px;
      overflow-y: scroll;
      padding: 10px;
    }

    .chat-content li {
      margin-top: 10px;
      list-style: none;
    }

    .text-small {
      font-size: 12px;
      color: gray;
      margin-bottom: 0;
    }

    .chat-box {
      background: #eee;
      padding: 5px;
      border-radius: 5px;
      float: left;
    }

    .mine {
      float: right;
    }
  </style>
</head>

<body>
  <%- include('nav.html')%>

  <div class="container p-4 detail">

    <div class="row">
      <div class="col-3">
        <ul class="list-group chat-list">
          <% for (let i = 0; i < data.length; i++ ) { %>
          <li class="list-group-item" data-id="<%= data[i]._id %>">
            <h6> <%= data[i].title %> </h6>
            <p class="text-small"> <%= data[i].nickname[0] %>, <%= data[i].nickname[1] %>님의 채팅</p>
          </li>
          <% } %>
        </ul>
      </div>

      <div class="col-9 p-0">
        <div class="chat-room">
          <ul class="list-group chat-content">
            <li><span class="chat-box">채팅방1 내용</span></li>
            <li><span class="chat-box">채팅방1 내용</span></li>
            <li><span class="chat-box mine">채팅방1 내용</span></li>
          </ul>
          <div class="input-group">
            <input class="form-control" id="chat-input">
            <button class="btn btn-secondary" id="send">전송</button>
          </div>
        </div>
      </div>
    </div>

  </div>


  <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous">
  </script>

  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>


  <script>
    let clickData = ''
    $('.list-group-item').click((e) => {
      console.log(e.currentTarget);
      clickData = e.currentTarget.dataset.id;
    })


    $('#send').click((e) => {
      const sendData = {
        parent: clickData,
        content: $('#chat-input').val()
      }

      $.ajax({
        method: 'post',
        url: '/msg',
        data: sendData
      }).then((r) => {
        console.log('전송 성공');
      })

    })
  </script>

  <script>
    $(function () {
      $("#file").on('change', function () {
        readURL(this); // 선택한 파일을 읽고, 해당 파일의 데이터 URL을 생성 후 파일을 처리
      });
    });

    function readURL(input) {
      if (input.files && input.files[0]) {
        var reader = new FileReader();
        reader.onload = function (e) {
          $('#preview').attr('src', e.target.result);
        }
        reader.readAsDataURL(input.files[0]);
      }
    }
  </script>

</body>

</html>