Files
comment/js/comment.js

301 lines
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ====================================================================
ОБЕРТКА ДЛЯ ОЖИДАНИЯ JQUERY
==================================================================== */
(function waitForJQuery() {
if (typeof jQuery === 'undefined') {
setTimeout(waitForJQuery, 10);
} else {
(function($) {
if (typeof aveabspath === 'undefined') {
window.aveabspath = '/';
}
/* --- ТАЙМЕРЫ --- */
function initCommentTimers() {
$('.timer-count:not(.timer-running)').each(function() {
var $timer = $(this);
$timer.addClass('timer-running');
var timeLeft = parseInt($timer.attr('data-left'));
var cid = $timer.attr('id').replace('timer_', '');
var countdown = setInterval(function() {
timeLeft--;
if (timeLeft <= 0) {
clearInterval(countdown);
$('#controls_' + cid).fadeOut(300);
$('#timer_container_' + cid).html('<span class="text-danger small">Время на правку истекло</span>');
return;
}
var minutes = Math.floor(timeLeft / 60);
var seconds = timeLeft % 60;
$timer.text(minutes + ':' + (seconds < 10 ? '0' : '') + seconds);
$timer.attr('data-left', timeLeft);
}, 1000);
$timer.data('interval-id', countdown);
});
}
/* Limit Plugin */
$.fn.extend({
limit: function(limit, element) {
return this.each(function() {
var self = $(this);
function substring() {
var val = self.val();
if (val.length > limit) self.val(val.substring(0, limit));
if (typeof element !== 'undefined') {
var remaining = limit - self.val().length;
$(element).html(remaining < 0 ? '0' : remaining);
}
}
self.on('focus keyup paste', substring);
substring();
});
}
});
function getCaptha() {
var now = new Date();
$('#captcha img').attr('src', aveabspath + 'inc/captcha.php?cd=' + now.getTime());
}
function validate(form) {
var checks = [
{ field: form.comment_author_name, msg: "Введите имя" },
{ field: form.comment_author_email, msg: "Введите Email" },
{ field: form.comment_text, msg: "Введите текст" }
];
for (var i = 0; i < checks.length; i++) {
if (checks[i].field && !checks[i].field.value.trim()) {
alert(checks[i].msg);
$(checks[i].field).focus();
return false;
}
}
return true;
}
/* --- ДЕЙСТВИЯ (DELETE, LOCK, OPEN/CLOSE, VOTE) --- */
function cAction(obj, action) {
var $btn = $(obj);
var cid = $btn.data('id');
if (!cid && action !== 'open' && action !== 'close') return;
$.get(aveabspath + 'index.php', {
module: 'comment',
action: action,
docid: typeof DOC_ID !== 'undefined' ? DOC_ID : '',
Id: cid ? cid : ''
}, function() {
if (action === 'close') {
$btn.attr('id', 'mod_comment_open')
.removeClass('btn-outline-danger').addClass('btn-outline-success')
.html('<i class="bi bi-lock-fill me-1"></i> ' + COMMENT_SITE_OPEN);
$('#mod_comment_new').fadeOut(300);
}
else if (action === 'open') {
$btn.attr('id', 'mod_comment_close')
.removeClass('btn-outline-success').addClass('btn-outline-danger')
.html('<i class="bi bi-unlock-fill me-1"></i> ' + COMMENT_SITE_CLOSE);
$('#mod_comment_new').fadeIn(300);
}
if (action === 'delete') {
var $commentBlock = $btn.closest('.mod_comment_comment');
$commentBlock.fadeOut(300, function() { $(this).remove(); });
}
if (action === 'unlock' || action === 'lock') {
var isLock = (action === 'lock');
$btn.toggleClass('mod_comment_lock mod_comment_unlock text-dark text-success')
.attr('title', isLock ? 'Разблокировать' : 'Заблокировать')
.find('i').toggleClass('bi-lock-fill bi-unlock-fill');
}
});
}
/* --- ИНИЦИАЛИЗАЦИЯ --- */
$(document).ready(function() {
initCommentTimers();
var $doc = $(document);
// --- ЛОГИКА ГОЛОСОВАНИЯ (РЕЙТИНГ) ---
$doc.on('mouseenter', '.star-item', function() {
$(this).prevAll().addBack().removeClass('bi-star').addClass('bi-star-fill');
$(this).nextAll().removeClass('bi-star-fill').addClass('bi-star');
});
$doc.on('mouseleave', '.comment-stars', function() {
// При уходе мыши визуально ничего не меняем до клика или рефреша
});
$doc.on('click', '.star-item', function() {
var $container = $(this).closest('.comment-rating-container');
var commentId = $container.data('id');
var voteValue = $(this).data('value');
$.ajax({
// Используем относительный путь для избежания проблем с протоколом HTTPS/HTTP
url: 'index.php?module=comment&action=vote&ajax=1',
type: 'POST',
data: {
comment_id: commentId,
vote: voteValue,
ajax: 1 // Дублируем для надежности
},
success: function(response) {
var res = response.toString().trim();
// Проверяем наличие ключевого слова в ответе (защита от варнингов PHP)
if (res.indexOf('success') !== -1) {
$container.html('<span class="text-success small fw-bold">Спасибо!</span>');
setTimeout(function(){ location.reload(); }, 1000);
} else if (res.indexOf('already_voted') !== -1) {
alert('Вы уже голосовали за этот комментарий.');
} else if (res.indexOf('own_comment') !== -1) {
alert('Нельзя голосовать за свой собственный комментарий.');
} else {
console.warn("Server response:", response);
alert('Ошибка при обработке голоса сервером.');
}
},
error: function(xhr) {
console.error("XHR Status:", xhr.status);
alert('Ошибка связи с сервером. Статус: ' + xhr.status);
}
});
});
// ------------------------------------
// Глобальные кнопки управления
$doc.on('click', '#mod_comment_close', function(e) {
e.preventDefault(); cAction(this, 'close');
});
$doc.on('click', '#mod_comment_open', function(e) {
e.preventDefault(); cAction(this, 'open');
});
// КНОПКА ОТВЕТА
$doc.off('click', '.mod_comment_answer').on('click', '.mod_comment_answer', function(e) {
e.preventDefault();
var cid = $(this).data('id');
var $form = $('#mod_comment_new');
$form.insertAfter('#comment_' + cid).show();
$('#parent_id').val(cid);
$('html, body').animate({
scrollTop: $form.offset().top - 150
}, 500);
$('#in_message').focus();
});
// Удаление
$doc.off('click', '.mod_comment_delete').on('click', '.mod_comment_delete', function(e) {
e.preventDefault();
if (confirm('Удалить этот комментарий?')) cAction(this, 'delete');
});
// Блокировка
$doc.off('click', '.mod_comment_lock, .mod_comment_unlock').on('click', '.mod_comment_lock, .mod_comment_unlock', function(e) {
e.preventDefault();
cAction(this, $(this).hasClass('mod_comment_lock') ? 'lock' : 'unlock');
});
// Редактирование
$doc.off('click', '.mod_comment_edit').on('click', '.mod_comment_edit', function(e) {
e.preventDefault();
var cid = $(this).data('id');
var $wrapper = $('#comment_wrapper_' + cid);
var $textBlock = $wrapper.find('.mod_comment_text').first();
if ($wrapper.find('.edit-form-container').length > 0) return;
$('.edit-form-container').remove();
$('.mod_comment_text').show();
var cleanText = $textBlock.html().replace(/<br\s*\/?>/mg, "\n").trim();
var currentImg = $wrapper.find('.mod_comment_attached_image img').first().attr('src');
var editHtml = `
<div class="edit-form-container border rounded p-3 bg-light mt-2 mb-2">
<textarea rows="5" id="ta_${cid}" class="form-control mb-2">${cleanText}</textarea>
${currentImg ? `<div class="form-check mb-2"><input class="form-check-input" type="checkbox" id="del_img_${cid}"><label class="form-check-label small text-danger" for="del_img_${cid}">Удалить фото</label></div>` : ''}
<input type="file" id="new_file_${cid}" class="form-control form-control-sm mb-3" accept="image/*">
<div class="d-flex gap-2">
<button type="button" class="btn btn-sm btn-primary saveButton" data-id="${cid}">Сохранить</button>
<button type="button" class="btn btn-sm btn-secondary cancelButton">Отмена</button>
<small class="ms-auto text-muted">Осталось: <span id="charsLeft_${cid}"></span></small>
</div>
</div>`;
$textBlock.hide().after(editHtml);
$('#ta_' + cid).limit(1000, '#charsLeft_' + cid).focus();
});
$doc.on('click', '.cancelButton', function() {
var $container = $(this).closest('.edit-form-container');
$container.prev('.mod_comment_text').show();
$container.remove();
});
$doc.on('click', '.saveButton', function() {
var $btn = $(this);
var cid = $btn.data('id');
var fd = new FormData();
fd.append('module', 'comment'); fd.append('action', 'edit'); fd.append('Id', cid);
fd.append('text', $('#ta_' + cid).val());
fd.append('delete_image', $('#del_img_' + cid).is(':checked') ? 1 : 0);
var file = $('#new_file_' + cid)[0].files[0];
if (file) fd.append('comment_image', file);
$.ajax({
url: aveabspath + 'index.php?ajax=1',
type: 'POST', data: fd, processData: false, contentType: false,
beforeSend: function() { $btn.prop('disabled', true).text('...'); },
success: function() { location.reload(); }
});
});
// Отправка новой формы (или ответа)
$doc.on('submit', '#mod_comment_new form', function(e) {
e.preventDefault();
if (!validate(this)) return false;
var $form = $(this);
var $btn = $form.find('[type="submit"]');
var originalBtnText = $btn.text();
$.ajax({
url: aveabspath + 'index.php?ajax=1',
type: 'POST',
data: new FormData(this),
processData: false,
contentType: false,
beforeSend: function() {
$btn.prop('disabled', true).text('Отправка...');
},
success: function(data) {
if (data.includes('wrong_securecode')) {
alert("Код капчи введен неверно!");
getCaptha();
$btn.prop('disabled', false).text(originalBtnText);
} else {
location.reload();
}
},
error: function() {
alert("Ошибка связи с сервером");
$btn.prop('disabled', false).text(originalBtnText);
}
});
});
$doc.on('click', '#captcha img, #reload_captcha', function(e) {
e.preventDefault(); getCaptha();
});
});
})(jQuery);
}
})();