window.currentUser = ""; window.isAdmin = ""; window.userLevel = 1; window.postAuthorId = ""; window.currentPage = 1; window.noMoreComments = false; window.ss_comment_token = "53c278583ce2fea0561b7eeb3bcdeb2b9f966d10406ed9cd51bba52ef38407e8"; window.currentSort = "best"; window.lastCommentId = localStorage.getItem("lastCommentId") || null; window.totalComments = localStorage.getItem("totalComments") || 0; var initialLoadComplete = false; var loadingMore = false; function updateRatingSummary(){ var params = "bo_table=" + encodeURIComponent(window.BO_TABLE || "") + "&wr_id=" + encodeURIComponent(window.WR_ID || ""); $.ajax({ url: RATING_SUMMARY_URL + "?" + params, method: "GET", dataType: "json", success: function(data){ if(data && data.success){ $("#ratingNumber").text(parseFloat(data.avg_rating).toFixed(1)); $("#score5Bar").css("width", data.score5Percent + "%"); $("#score4Bar").css("width", data.score4Percent + "%"); $("#score3Bar").css("width", data.score3Percent + "%"); $("#score2Bar").css("width", data.score2Percent + "%"); $("#score1Bar").css("width", data.score1Percent + "%"); $("#score5Count").text(data.score5Count + "명"); $("#score4Count").text(data.score4Count + "명"); $("#score3Count").text(data.score3Count + "명"); $("#score2Count").text(data.score2Count + "명"); $("#score1Count").text(data.score1Count + "명"); } } }); } function toggleContent() { const previewBlock = document.getElementById('previewBlock'); const fullContent = document.getElementById('fullContent'); const button = document.getElementById('toggleBtn'); if (!previewBlock || !fullContent || !button) return; fullContent.classList.toggle('d-none'); previewBlock.classList.toggle('d-none'); if (fullContent.classList.contains('d-none')) { button.textContent = "... [더보기]"; } else { button.textContent = "[간략히 보기]"; } } (function($){ function debounce(func, wait) { var timeout; return function() { var context = this, args = arguments; clearTimeout(timeout); timeout = setTimeout(function(){ func.apply(context, args); }, wait); }; } function jsTimeAgo(dateString) { var ts = new Date(dateString.replace(/-/g,'/')).getTime(); var now = new Date().getTime(); var diff = Math.floor((now - ts) / 1000); if(diff < 0) diff = 0; var mins = Math.floor(diff / 60); var hours = Math.floor(mins / 60); var days = Math.floor(hours / 24); var months = Math.floor(days / 30); var years = Math.floor(days / 365); if(hours < 1 && mins >= 1) return mins + "분 전"; if(mins < 1) return "1분 전"; if(days < 1) return hours + "시간 전"; if(months < 1) return days + "일 전"; if(years < 1) return months + "달 전"; return years + "년 전"; } function showSpinner(){ if($("#temp-spinner").length === 0){ var $spinner = $("
Loading...
"); $("#comment-list").append($spinner); } } function hideSpinner(){ $("#temp-spinner").remove(); } function loadComments(page = 1, sort = "best", cursor_id = null){ var params = "page=" + page + "&header=" + (page === 1 ? 1 : 0) + "&sort=" + encodeURIComponent(sort); params += "&wr_id=" + encodeURIComponent(window.WR_ID || ""); params += "&bo_table=" + encodeURIComponent(window.BO_TABLE || ""); if(cursor_id) params += "&cursor_id=" + encodeURIComponent(cursor_id); var url = window.COMMENT_LIST_URL + "?" + params; showSpinner(); $.ajax({ url: url, method: "GET", success: function(response){ var $parsed = $(response); var $list = $parsed.is("#comment-list") ? $parsed : $parsed.find("#comment-list"); $("#comment-list").html($list.html()); var $tc = $parsed.find("#total-comments"); if($tc.length){ var totalComments = parseInt($tc.text()); localStorage.setItem("totalComments", totalComments); $("#total-comments").text($tc.text()); window.maxPage = Math.ceil(totalComments / 10); } var lastCommentId = $parsed.find("#last-comment-id").text(); if(lastCommentId) { localStorage.setItem("lastCommentId", lastCommentId); window.lastCommentId = lastCommentId; } hideSpinner(); initialLoadComplete = true; if (totalComments === 0) { window.noMoreComments = true; } }, error: function(){ hideSpinner(); initialLoadComplete = true; } }); } $(document).on("click", ".sort-option", function(e){ e.preventDefault(); $(".sort-option").removeClass("active"); $(this).addClass("active"); var sortType = $(this).data("sort") || ""; window.currentSort = sortType; window.currentPage = 1; window.lastCommentId = null; window.noMoreComments = false; window.maxPage = 1; initialLoadComplete = false; $("#comment-list").empty(); loadComments(1, sortType); $(window).off("scroll.parentComments").on("scroll.parentComments", debounce(loadMoreComments, 200)); }); function loadMoreComments() { if (!initialLoadComplete || window.noMoreComments || loadingMore) return; if ($(window).scrollTop() + $(window).height() > $(document).height() * 0.5) { loadingMore = true; var ci = $(".comment-item").last().data("comment-id") || 0; var srt = window.currentSort || "best"; if (ci === window.lastCommentId || !ci || window.currentPage >= window.maxPage) { window.noMoreComments = true; hideSpinner(); loadingMore = false; return; } var nextPage = window.currentPage + 1; var urlParams = "page=" + nextPage + "&header=0"; urlParams += "&sort=" + encodeURIComponent(srt); urlParams += "&wr_id=" + encodeURIComponent(window.WR_ID || ""); urlParams += "&bo_table=" + encodeURIComponent(window.BO_TABLE || ""); urlParams += "&cursor_id=" + encodeURIComponent(ci); var url = window.AJAX_COMMENT_LIST_URL + "?" + urlParams; var spinnerTimeout = setTimeout(showSpinner, 200); $.ajax({ url: url, method: "GET", dataType: "json", success: function(response) { clearTimeout(spinnerTimeout); if (response.success && response.comments.length > 0) { for (var i = 0; i < response.comments.length; i++) { addNewParentCommentDOM(response.comments[i]); } window.currentPage++; window.lastCommentId = response.last_comment_id; localStorage.setItem("lastCommentId", response.last_comment_id); window.maxPage = Math.ceil(response.total_comments / 10); if (response.comments.length < 10 || window.currentPage >= window.maxPage) { window.noMoreComments = true; } } else { window.noMoreComments = true; $(window).off("scroll.parentComments"); } hideSpinner(); loadingMore = false; }, error: function() { clearTimeout(spinnerTimeout); hideSpinner(); loadingMore = false; } }); } } $(document).ready(function(){ if (window.lastCommentId && window.lastCommentId !== "null") { loadComments(1, "best", window.lastCommentId); } else { loadComments(1, "best"); } $(window).off("scroll.parentComments").on("scroll.parentComments", debounce(loadMoreComments, 200)); $(document).on("focus", "#parent-comment-form .comment-input", function(){ if(window.currentOpenFormType === "edit" && typeof cancelParentEdit === "function"){ cancelParentEdit(); } if(window.currentOpenFormType === "reply" && typeof resetReplyList === "function"){ resetReplyList(); } window.currentOpenFormType = "parent"; var $f = $(this).closest("form"); if($(".reply-form-container").length){ $(".reply-form-container").remove(); } $f.find("#star-rating-block, .user-info, #secret-check, .reply-buttons, #cancel-comment-btn, #submit-button").removeClass("d-none"); var s = parseFloat($f.find("#wr_star").val()); $(this).attr("placeholder", s <= 0 ? "별점을 선택해야 댓글 작성이 가능합니다!" : "댓글을 입력하세요..."); $f.find("#submit-button").prop("disabled", false); }); $(document).on("input", "#parent-comment-form .comment-input", function(){ var $f = $(this).closest("form"); var $b = $f.find("#submit-button"); var v = $(this).val().trim(); if(v !== ""){ $b.prop("disabled", false).removeClass("d-none"); } else { $b.prop("disabled", true).addClass("d-none"); } }); $(document).on("click", "#star-rating-block .fa-star", function(){ var v = $(this).data("value"); var $f = $(this).closest("form"); $f.find("#wr_star").val(v); $(this).siblings().removeClass("active"); $(this).addClass("active").prevAll(".fa-star").addClass("active"); $f.find("#parent-comment-input").attr("placeholder", "댓글을 입력하세요..."); }); $(document).on("click", "#cancel-comment-btn", function(e){ e.preventDefault(); var $f = $(this).closest("form"); resetParentCommentForm($f); window.currentOpenFormType = null; }); $(document).on("click", "#parent-comment-form #submit-button", function(e){ e.preventDefault(); var $f = $(this).closest("form"); var sv = parseFloat($f.find("#wr_star").val()); if(sv <= 0){ alert("별점을 선택해야 댓글을 등록할 수 있습니다."); return; } var fd = new FormData($f[0]); $.ajax({ url: (typeof AJAX_COMMENT_ACTION_URL !== "undefined") ? AJAX_COMMENT_ACTION_URL : "/comment/comment_action.php", type: "POST", data: fd, processData: false, contentType: false, dataType: "json", success: function(r){ if(r.success){ resetParentCommentForm($f); if(r.total_comments !== undefined){ $("#total-comments").text(r.total_comments); } if(r.comment && typeof addNewParentCommentDOM === "function"){ r.comment.is_new = true; addNewParentCommentDOM(r.comment); updateParentReplyCount(r.comment.wr_parent, r.total_comments); } updateRatingSummary(); window.currentOpenFormType = null; } else { alert(r.message || "댓글 등록에 실패했습니다."); } }, error: function(){ alert("서버 통신 오류"); } }); }); $(document).on("click", ".post-like-btn", function(e) { e.preventDefault(); var $btn = $(this); var postId = $btn.data("id"); var liked = ($btn.attr("data-liked") === "true"); var action = liked ? "cancel" : "recommend"; $.ajax({ url: window.AJAX_COMMENT_RECOMMEND_URL, // 이 변수는 common.php나 output_global_js_variables()에서 설정되어야 함. type: "POST", dataType: "json", data: { wr_id: postId, action: action, ss_comment_token: window.ss_comment_token, bo_table: window.BO_TABLE // 이 값도 전역 변수로 설정되어야 함. }, success: function(response) { if (response && response.success) { $btn.find("span").text(response.newCount > 0 ? response.newCount : ""); if (action === "recommend") { $btn.find("i").removeClass("far").addClass("fas"); $btn.attr("data-liked", "true"); } else { $btn.find("i").removeClass("fas").addClass("far"); $btn.attr("data-liked", "false"); } } else { alert(response && response.message ? response.message : "추천 처리에 실패했습니다."); } }, error: function(xhr, status, error) { alert("추천 요청 중 오류가 발생했습니다: " + error); } }); }); function resetParentCommentForm($f){ if($f[0]) $f[0].reset(); $f.find("#wr_star").val("0"); $f.find(".fa-star").removeClass("active"); $f.find("#star-rating-block, .user-info, #secret-check, .reply-buttons, #cancel-comment-btn, #submit-button").addClass("d-none"); $f.find("#submit-button").prop("disabled", true); $f.find("#parent-comment-input").attr("placeholder", "댓글을 입력하세요..."); } window.resetParentCommentForm = resetParentCommentForm; }); window.updateParentReplyCount = function(pid, cnt){ cnt = (typeof cnt === "undefined" || isNaN(cnt)) ? 0 : cnt; var $p = $("#comment_" + pid); var $r = $p.find(".reply-count-link"); if($r.length){ $r.text("답글 " + cnt + "개"); $p.attr("data-child-count", cnt); } }; window.addNewParentCommentDOM = function(c) { var h = (c.wr_content || "").replace(//g, ">").replace(/\n/g, "
"); var lockIcon = ''; if (c.wr_option === "secret") { if (h === "비밀글입니다.") { h = lockIcon + " 비밀글입니다."; } else { h = lockIcon + " " + h; } } var s = parseFloat(c.wr_star || 0), sh = ""; if (s > 0) { sh += '
'; for (var i = 1; i <= 5; i++){ sh += ''; } sh += '
' + s.toFixed(1) + '
'; } var cid = c.wr_id; var rawDate = c.wr_datetime || ""; var commentDate = rawDate; if (typeof jsTimeAgo === "function") { commentDate = jsTimeAgo(rawDate); } var isLiked = c.is_liked; var isPinned = (c.wr_10 === "1"); var x = '
  • '; x += '
    '; x += 'Profile'; x += '
    '; if (isPinned) { x += '
    ' + (c.commenter_name || "Anonymous") + '님이 고정함
    '; } x += '
    '; x += '
    '; x += ' ' + (c.commenter_name || "Anonymous") + ''; x += ' '+ commentDate +''; if(window.isAdmin === "admin" || window.isAdmin === "super"){ x += ' ' + c.wr_ip + ''; } x += '
    '; x += ' '; x += '
    '; if (s > 0) x += sh; x += '
    ' + h + '
    '; x += ''; if(c.child_count > 0) { x += '
    '; } else { x += ''; x += '
    '; x += '
    '; x += '
    '; x += '
  • '; var $container = $("#comment-list"); var $pinned = $container.children("li.comment-item[data-pinned='1']"); var $allComments = $container.children("li.comment-item"); if(c.is_new){ if(isPinned){ if($pinned.length){ $pinned.last().after(x); } else { var $firstComment = $container.children("li.comment-item").first(); if($firstComment.length){ $firstComment.before(x); } else { $container.append(x); } } } else { if($pinned.length){ $pinned.last().after(x); } else { var $firstComment = $allComments.first(); if($firstComment.length){ $firstComment.before(x); } else { $container.append(x); } } } } else { if(window.currentPage === 1 && isPinned){ if($pinned.length){ $pinned.last().after(x); } else { var $firstComment = $allComments.first(); if($firstComment.length){ $firstComment.before(x); } else { $container.append(x); } } } else { $container.append(x); } } }; })(jQuery);