[TIL] 220104

Lee Syong·2022년 1ė›” 4ėž
0

TIL

ëŠĐ록 ëģīęļ°
139/204
post-thumbnail

📝 ė˜Ī늘 한 ęēƒ

  1. ëģĩėŠĩ - COMMENT SECTION

📚 ë°°ėšī ęēƒ (ëģĩėŠĩ)

ė „ėēī ė―”드는 githubė— ė˜ŽëĶž(wetube_v2)

13. COMMENT SECTION

  • [TIL] 211218
    • ëē„ę·ļ ėˆ˜ė • (ėķ”ę°€)
    • 댓ęļ€ ė‚­ė œ ęļ°ëŠĨ ėķ”ę°€

â€ŧ ëē„ę·ļ ėˆ˜ė •

  • textareaė— ėž…ë Ĩ한 ėĪ„ë°”ęŋˆėī ė‹Īė œ 댓ęļ€ëž€ė—ė„œ 띄ė–īė“°ęļ°ëĄœ 표ė‹œë˜ëŠ” ëŽļė œę°€ ėžˆė—ˆë‹Ī

→ ėž‘ė„ąí•œ 댓ęļ€ ë‚īėšĐė„ 받는 p 태ę·ļė— white-space: pre-wrap ė†ė„ąė„ ėĢžė—ˆë‹Ī.

.show-comment__text {
  margin-top: 0.7rem;
  line-height: 1.5rem;
  white-space: pre-wrap;
}
  • ėē˜ėŒ 로ę·ļėļ한 ęģ„ė •ė„ 로ę·ļė•„ė›ƒí•˜ęģ  ë‹ĪëĨļ ęģ„ė •ėœžëĄœ 로ę·ļėļ한 후 댓ęļ€ė„ ėž‘ė„ąí•˜ëĐī ė‹Īė‹œę°„ėœžëĄœ ëœĻ는 댓ęļ€ėī ėīė „ 로ę·ļėļ ęģ„ė • ė •ëģī로 ëœĻ는 ëŽļė œę°€ ėžˆė—ˆë‹Ī.

→ ė‹Īė‹œę°„ėœžëĄœ 댓ęļ€ė„ 띄ėš°ëŠ” 프론íŠļė—”ë“œ ė―”ë“œëĄœ ė „í•īėĪ„ data ė†ė„ąė˜ 값ė„ comment.ownerė—ė„œ loggedInUser 값ėœžëĄœ 바ęŋĻë‹Ī.

mixin comment(comment)
  div.comment-container__item(data-logged-in-user=loggedInUser)
ownerNameLink.textContent = JSON.parse(commentMixinItem.dataset.loggedInUser).name;
  • textareaė—ė„œ 댓ęļ€ ėž‘ė„ąė„ ė·Ļė†Œí•˜ęą°ë‚˜ 댓ęļ€ė„ ė œėķœí–ˆė„ 때 textareaė˜ 높ėī가 ęļ°ëģļ 높ėī로 ėžë™ėœžëĄœ ė•ˆ 돌ė•„ė˜Ī는 ëŽļė œę°€ ėžˆė—ˆë‹Ī.

→ ė·Ļė†Œ ëē„튞 íīëĶ­ ė‹œ textareaė˜ 높ėī가 ėžë™ėœžëĄœ ęļ°ëģļ 높ėī가 되도록 ėˆ˜ė •í–ˆë‹Ī. 댓ęļ€ė„ ė œėķœí•˜ęģ  201 ėƒíƒœ ė―”ë“œëĨž ëģī냈ė„ 때도 ė•„래 í•Ļėˆ˜ę°€ ė‹Ī행된ë‹Ī.

const handleCancelBtnClick = () => {
  textarea.value = "";
  buttonsDiv.remove();
  textarea.style.height = "1.5rem"; // ėķ”ę°€
};
  • ėž‘ė„ąëœ 댓ęļ€ėī 하나도 ė—†ė„ 때 댓ęļ€ė„ ėž‘ė„ąí•˜ë Īęģ  하ëĐī ė—ëŸŽę°€ ë–īë‹Ī. data ė†ė„ąė„ 댓ęļ€ėī ėž‘ė„ąë˜ė–īė•žë§Œ 만ë“Īė–īė§€ëŠ” mixin itemė— ëķ€ė—Ží–ˆęļ° 때ëŽļė— í•īë‹đ ėš”ė†ŒëĨž ė―ė–īė˜Ž ėˆ˜ ė—†ė–ī ė—ëŸŽę°€ 발ėƒí•œ ęēƒėīė—ˆë‹Ī.

→ commentMixinItem 대ė‹  commentContainerShowė— data ė†ė„ąė„ ėķ”ę°€í–ˆë‹Ī.

  ownerNameLink.textContent = JSON.parse(
    commentContainerShow.dataset.loggedInUser
  ).name;
  • data ė†ė„ąė„ videoė—ė„œ videoContainer로 바ęūž 후 ėĄ°íšŒėˆ˜ëĨž ė—…데ėīíŠļ하는 fetchëĨž ėˆ˜ė •í•īėĢžė§€ ė•Šė•„ė„œ ė—ëŸŽę°€ 발ėƒí–ˆë‹Ī.

→ ${video.dataset.videoId} ëĨž ${JSON.parse(videoContainer.dataset.video)._id} 로 ėˆ˜ė •í–ˆë‹Ī.

const handleVideoEnded = async () => {
  video.currentTime = 0;
  playBtn.innerHTML = "<i class='fas fa-play'></i>";
  await fetch(
    `/api/videos/${JSON.parse(videoContainer.dataset.video)._id}/views`,
    {
      method: "POST",
    }
  );
};
  • 동ė˜ėƒė˜ createdAtėī ė›í•˜ëŠ” 대로 ëģīėīė§€ ė•Šė•„ ėˆ˜ė •í–ˆë‹Ī.
span.video-data-container__createdAt #{video.createdAt.getFullYear()}. #{String(video.createdAt.getMonth() + 1).padStart(2, "0")}. #{String(video.createdAt.getDate()).padStart(2, "0")}.
  • 댓ęļ€ė„ ėķ”ę°€í•˜ęģ  ė‚­ė œí•  때 댓ęļ€ 개ėˆ˜ëĨž ė‹Īė‹œę°„ėœžëĄœ 표ė‹œí•˜ëŠ” ė―”ë“œė— ëŽļė œę°€ ėžˆė—ˆë‹Ī. 댓ęļ€ė„ 2ëēˆ ėīėƒ ė—°ė†ėœžëĄœ ėķ”ę°€í•˜ęą°ë‚˜ ė‚­ė œí•˜ëĐī ė‹Īė‹œę°„ ė—…데ėīíŠļ가 되ė§€ ė•Šė•˜ë‹Ī.

→ commentCount ëģ€ėˆ˜ëĨž 따로 만ë“Īė–ī ė—…데ėīíŠļ하는 ë°Đė‹ėœžëĄœ ė―”ë“œëĨž ėˆ˜ė •í–ˆë‹Ī.

let commentCount = JSON.parse(videoContainer.dataset.video).comments.length;

const addComment = (commentText, commentId) => {
  // ėĪ‘ëžĩ
  commentCount++;
  commentContainerCount.textContent = `댓ęļ€ ${commentCount}개`;
};

const handleCommentContainerShowClick = async (event) => {
  // ėĪ‘ëžĩ
  commentCount--;
  commentContainerCount.textContent = `댓ęļ€ ${commentCount}개`;
};

ðŸ’Ą 댓ęļ€ ė‚­ė œ ęļ°ëŠĨ ėķ”ę°€

const addComment = (commentText, commentId) => {
  // ėĪ‘ëžĩ
};

const handleCancelBtnClick = () => {
  textarea.value = "";
  textarea.style.height = "1.5rem";
  buttonsDiv.remove();
};

const handleSubmit = async (event) => {
  event.preventDefault();
  const text = textarea.value;
  if (text === "") {
    return;
  }
  const videoId = JSON.parse(videoContainer.dataset.video)._id;
  const response = await fetch(`/api/videos/${videoId}/comments`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ text }),
  });
  if (response.status === 201) {
    const { newCommentId } = await response.json();
    addComment(text, newCommentId);
    handleCancelBtnClick();
  }
};

const handleCommentContainerShowClick = async (event) => {
  const commentId = event.target.dataset.commentId;
  const className = event.target.className;
  if (
    commentId &&
    (className === "fas fa-trash" || "show-comment__delete-button")
  ) {
    const response = await fetch(`/api/comments/${commentId}`, {
      method: "DELETE",
    });
    if (response.status === 200) {
      const toBeDeleted = commentContainerShow.querySelector(
        `.comment-container__item[data-comment-id="${commentId}"]`
      );
      toBeDeleted.remove();
      commentCount--;
      commentContainerCount.textContent = `댓ęļ€ ${commentCount}개`;
    }
  }
};

form.addEventListener("submit", handleSubmit);
commentContainerShow.addEventListener("click", handleCommentContainerShowClick);

âœĻ ë‚īėž 할 ęēƒ

  1. ëģĩėŠĩ ęģ„ė†í•˜ęļ° - DEPLOYMENT
profile
ëŠĨ동ė ėœžëĄœ ė‚īėž, 행ëģĩ하ęēŒðŸ˜

0개ė˜ 댓ęļ€