window.currentUser = "";
window.isAdmin = "";
window.userLevel = 1;
window.postAuthorId = "";
window.currentPage = 1;
window.noMoreComments = false;
window.ss_comment_token = "5e1a08cde5a656ea8b2241b18b58534a5fcecfe0fedf509879a6e50f337f022b";
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 = $("
");
$("#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 = '