ė ėēī ė―ëë githubė ėŽëĶž(wetube_v2)
âŧ ëēę·ļ ėė
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);